diff --git a/build.xml b/build.xml
index 95b058c..9b4046c 100644
--- a/build.xml
+++ b/build.xml
@@ -76,13 +76,11 @@
     <fileset dir="${lib.dir}">
       <!--include name="guice-3.0.jar"/-->
       <include name="jsr305.jar"/>
-      <include name="servlet-api.jar"/>
 
       <!-- Dependencies that are in common with opensaml. -->
       <include name="joda-time-1.6.jar"/>
       <include name="opensaml-2.3.2.jar"/>
       <include name="openws-1.3.1.jar"/>
-      <include name="slf4j-api-1.5.10.jar"/>
       <include name="xmltooling-1.2.2.jar"/>
     </fileset>
   </path>
diff --git a/lib/servlet-api.jar b/lib/servlet-api.jar
deleted file mode 100644
index e76311f..0000000
--- a/lib/servlet-api.jar
+++ /dev/null
Binary files differ
diff --git a/src/com/google/common/base/Pair.java b/src/com/google/common/base/Pair.java
deleted file mode 100644
index 11b94cb..0000000
--- a/src/com/google/common/base/Pair.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/* Copyright (c) 2008 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.common.base;
-
-import java.io.Serializable;
-/**
- * Pair is an expedient way to combine two arbitrary objects into one.  <b>Its
- * use is not to be preferred</b> to creating a custom type, but it can be
- * handy in a pinch.  If your {@link #equals}, {@link #hashCode},
- * {@link #toString}, and/or {@link #clone} behavior matter to you at all, you
- * may not want to use this (or you may at least wish to subclass).
- *
- *
-
- *
- * <p>This class may be used with the Google Web Toolkit (GWT).
- *
- */
-public class Pair<A,B> implements Serializable, Cloneable {
-  private static final long serialVersionUID = 747826592375603043L;
-
-  /** Creates a new pair containing the given objects in order. */
-  public static <A,B> Pair<A,B> of(A first, B second) {
-    return new Pair<A,B>(first, second);
-  }
-
-  /** The first element of the pair. */
-  public final A first;
-
-  /** The second element of the pair. */
-  public final B second;
-
-  /** Cumbersome way to create a new pair (see {@link #of}. */
-  public Pair(A first, B second) {
-    this.first = first;
-    this.second = second;
-  }
-
-  /** Optional accessor method for {@link #first}. */
-  public A getFirst() {
-    return first;
-  }
-
-  /** Optional accessor method for {@link #second}. */
-  public B getSecond() {
-    return second;
-  }
-
-  @Override public Pair<A,B> clone() {
-    try {
-      @SuppressWarnings("unchecked")
-      Pair<A,B> result = (Pair<A,B>) super.clone();
-      return result;
-    } catch (CloneNotSupportedException e) {
-      throw new AssertionError(e);
-
-
-
-
-
-    }
-  }
-
-  @Override public boolean equals(Object object) {
-
-
-    if (object instanceof Pair<?,?>) {
-      Pair<?,?> other = (Pair<?,?>) object;
-      return eq(first, other.first) && eq(second, other.second);
-    }
-    return false;
-  }
-
-  @Override public int hashCode() {
-    /*
-     * This combination yields entropy comparable to constituent hashes
-     * and ensures that hash(a,b) != hash(b,a).
-     */
-    return (hash(first, 0) + 0xDeadBeef) ^ hash(second, 0);
-  }
-
-  /**
-   * This implementation returns the String representation of this pair in
-   * the form {@code (string1, string2)}, where {@code string1} and
-   * {@code string2} are the {@link Object#toString} representations of the
-   * elements inside the pair.
-   */
-  @Override public String toString() {
-    return String.format("(%s, %s)", first, second);
-  }
-
-
-  private static boolean eq(Object a, Object b) {
-    return a == b || (a != null && a.equals(b));
-  }
-
-  private static int hash(Object object, int nullHash) {
-    return (object == null) ? nullHash : object.hashCode();
-  }
-}
diff --git a/src/com/google/common/labs/matcher/ParsedUrlPattern.java b/src/com/google/common/labs/matcher/ParsedUrlPattern.java
deleted file mode 100644
index 31812c9..0000000
--- a/src/com/google/common/labs/matcher/ParsedUrlPattern.java
+++ /dev/null
@@ -1,621 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.common.labs.matcher;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import com.google.common.base.Preconditions;
-
-/**
- * This class parses a Google URL pattern into an immutable representation that
- * provides equivalent Java regexes,
- * exact-match patterns and prefix patterns, as appropriate. For a description
- * of Google URL patterns, see the
- * documentation in <a
- * href="http://code.google.com/apis/searchappliance/documentation/50/admin/URL_patterns.html">
- * this document</a>.
- * <p>
- * All Google URL patterns can be translated into an equivalent Java regex (with
- * some exceptions and caveats, see below). This class provides access to an
- * equivalent Java regex through {@link #getUrlRegex()}.
- * <p>
- * In addition, the class provides further analysis and special kinds of
- * patterns, depending on these top-level predicates:
- * <ul>
- * <li> {@link #isHostPathType()}: Returns {@code true} if the parsed pattern
- * is a "host-path" pattern. A "host-path" pattern is a pattern that can be
- * parsed into two regexes, a host regex and a path regex, such that a subject
- * URL matches the original URL pattern iff the host portion matches the host
- * regex and the path portion matches the path regex. If
- * {@code isHostPathType()} is true, then {@link #getHostRegex()} and
- * {@link #getPathRegex()} return the corresponding regexes. </li>
- * <li> {@link #isPathPrefixMatch()}: Returns {@code true} if the parsed
- * pattern is a "host-path" pattern and the path portion of the pattern is
- * simply a fixed string that must appear at the beginning of the path. In this
- * case, {@link #getPathPrefixString()} returns a simple string (not a regex)
- * that can be matched against the start of the subject URL's path. </li>
- * <li> {@link #isPathExactMatch()}: Returns {@code true} if if the parsed
- * pattern is a "host-path" pattern and the path portion of the pattern is an
- * exact-match string. In this case, {@link #getPathExactString()} returns a
- * simple string (not a regex) that can be matched exactly against the subject
- * URL's path. </li>
- * </ul>
- * In summary:
- * <ul>
- * <li> {@code getUrlRegex()} provides an equivalent Java regex for the entire
- * pattern. </li>
- * <li> If {@code isHostPathType()} is true, then, {@code getHostRegex()} and
- * {@code getPathRegex()} return regexes for the two portions.</li>
- * <li> If {@code isPrefixPathMatch()} is true, then,
- * {@code getPrefixPathMatchPattern()} returns a simple string pattern for
- * prefix match.</li>
- * <li> If {@code isPathExactMatch()} is true, then, in addition,
- * {@code getPathExactMatchPattern()} returns a simple string pattern for exact
- * match.
- * </ul>
- * <p>
- * Note: the "path" portion is the hierarchical part, that is, everything
- * following the first slash (not the {@code ://}). The "host" portion is
- * everything before that. For example: for the URL
- * {@code http://www.example.com/foo/bar}, the protocol-authority portion is
- * {@code http://www.example.com/} and the file portion is {@code /foo/bar}.
- * Note the the middle slash appears in both portions.
- * <p>
- * A parser is provided to separate a URL string into host and path portions:
- * {@link AnalyzedUrl}. You can access the host and path portions through
- * {@link AnalyzedUrl#getHostPart()} and {@link AnalyzedUrl#getPathPart()}. It
- * is recommended that this parser be used rather than the standard
- * {@code getHost()} and {@code getPath()} functions of {@link java.net.URL},
- * because this class and {@code AnalyzedUrl} share parsing infrastructure and
- * at present, there is at least one significant difference:
- * {@code AnalyzedUrl.getPathPart()} includes the leading slash but
- * {@code java.net.URL.getPath()} does not. TODO: fix this.
- * <p>
- * Exceptions and caveats: not all forms of Google URL patterns are currently
- * supported. At present, these exceptions and special cases apply:
- * <ul>
- * <li> {@code www?:} patterns are not supported </li>
- * <li> {@code regexp:} and {@code regexpCase:} patterns are translated simply
- * by removing those two prefixes. Thus, the remaining pattern is assumed to be
- * a Java regex, not a GNU regex (as documented on the <a
- * href="http://code.google.com/apis/searchappliance/documentation/50/admin/URL_patterns.html">
- * reference site</a>). </li>
- * <li> {@code regexpIgnoreCase:} patterns are handled similarly. In this case,
- * the prefix is removed and the pattern is enclosed in {@code (?i:}...{@code )}</li>
- * <li> Exception patterns (patterns with leading {@code -} or {@code +-}) are
- * not supported.</li>
- * </ul>
- */
-public class ParsedUrlPattern {
-
-  private final String urlPattern;
-  private final String urlRegex;
-
-  private final boolean hostPathType;
-  private final String hostRegex;
-
-  private final String pathRegex;
-  private final boolean pathExactMatch;
-  private final String pathExactMatchPattern;
-
-  private final boolean prefixPathMatch;
-  private final String prefixPathMatchPattern;
-
-  /**
-   * Parses a Google URL pattern to Java regexes. Google URL patterns are
-   * publicly documented <a
-   * href="http://code.google.com/apis/searchappliance/documentation/50/admin/URL_patterns.html">
-   * here </a>.
-   * 
-   * @param urlPattern A Google URL pattern
-   * @throws IllegalArgumentException if the URL pattern is unsupported or can
-   *         not be parsed
-   */
-  public ParsedUrlPattern(String urlPattern) {
-    ParsedUrlPatternBuilder t = new ParsedUrlPatternBuilder(urlPattern);
-    this.urlPattern = t.urlPattern;
-    this.urlRegex = t.urlRegex;
-    this.hostPathType = t.hostPathType;
-    this.hostRegex = t.hostRegex;
-    this.pathRegex = t.pathRegex;
-    this.pathExactMatch = t.pathExactMatch;
-    this.pathExactMatchPattern = t.pathExactMatchPattern;
-    this.prefixPathMatch = t.prefixPathMatch;
-    this.prefixPathMatchPattern = t.prefixPathMatchPattern;
-
-  }
-
-  /**
-   * Returns a regex that matches the entire URL. A subject string matches the
-   * URL pattern iff it matches this regex.
-   * 
-   * @return a regex that matches the entire URL
-   */
-  public String getUrlRegex() {
-    return urlRegex;
-  }
-
-  /**
-   * Returns {@code true} if the parsed pattern is a "host-path" pattern. A
-   * "host-path" pattern is a pattern that can be parsed into two regexes, a
-   * host regex and a path regex, such that a subject url matches the pattern
-   * iff the host portion matches the host regex and the path portion matches
-   * the path regex.
-   * <p>
-   * For example, the pattern {@code example.com/foo} might be parsed into two
-   * regexes, host regex: {@code example.com/$} and path regex: {@code ^/foo}.
-   */
-  public boolean isHostPathType() {
-    return hostPathType;
-  }
-
-  /**
-   * Returns a regex that matches the host (protocol and authority) portion of
-   * the URL. If this is a host-path regex then a subject string matches the url
-   * pattern iff the host portion matches this regex and the the path portion
-   * matches the corresponding path regex (obtained by {@link #getPathRegex()}).
-   * <p>
-   * This should be used against URLs that have been parsed using the
-   * {@link AnalyzedUrl} class.
-   * <p>
-   * Note: this should only be used if {@code isHostPathType()} is true; if not,
-   * then this method throws an {@code IllegalStateException}.
-   * 
-   * @return a regex that matches the host (protocol and authority) portion of
-   *         the URL
-   * @throws IllegalStateException if {@code isHostPathType()} is false
-   */
-  public String getHostRegex() {
-    Preconditions.checkState(isHostPathType());
-    return hostRegex;
-  }
-
-  /**
-   * Returns a regex that matches the path (hierarchical) portion of the URL.
-   * <p>
-   * This should be used against URLs that have been parsed using the
-   * {@link AnalyzedUrl} class.
-   * <p>
-   * Note: this should only be used if {@link #isHostPathType()} is true; if
-   * not, then this method throws an {@code IllegalStateException}.
-   * 
-   * @return a regex that matches the path (hierarchical) portion of the URL
-   * @throws IllegalStateException if {@code isHostPathType()} is false
-   */
-  public String getPathRegex() {
-    Preconditions.checkState(isHostPathType());
-    return pathRegex;
-  }
-
-  /**
-   * Indicates whether the parsed pattern gives a prefix match pattern. If this
-   * is true, then this pattern can be obtained using
-   * {@link #getPathPrefixString()}.
-   * 
-   * @return {@code true} if the parsed pattern gives an prefix match pattern.
-   */
-  public boolean isPathPrefixMatch() {
-    return prefixPathMatch;
-  }
-
-  /**
-   * If {@link #isPathPrefixMatch()} is true, then this returns a simple string
-   * that can be matched against the path portion of a subject string using
-   * {@link String#startsWith(String)}.
-   * <p>
-   * Note: this should only be used if {@code isPrefixPathMatch()} is true; if
-   * not, then this method throws an {@code IllegalStateException}.
-   * 
-   * @return a string that matches a prefix of the path portion of the URL
-   * @throws IllegalStateException if {@code isPathPrefixMatch()} is false
-   */
-  public String getPathPrefixString() {
-    Preconditions.checkState(isPathPrefixMatch());
-    return prefixPathMatchPattern;
-  }
-
-  /**
-   * Returns whether the parsed pattern gives an exact match pattern. If this is
-   * true, then this pattern can be obtained using {@link #getPathExactString()}.
-   * 
-   * @return {@code true} if the parsed pattern gives an exact match pattern.
-   */
-  public boolean isPathExactMatch() {
-    return pathExactMatch;
-  }
-
-  /**
-   * If {@link #isPathExactMatch()} is true, then this returns a simple string
-   * that can be matched against the path portion of a subject string using
-   * {@link String#equals(Object)}. Note: this should only be used if
-   * {@code isPathExactMatch()} is true; if not, then this method throws an
-   * {@code IllegalStateException}.
-   * 
-   * @return a string that matches the entire path
-   * @throws IllegalStateException if {@code isPathExactMatch()} is false
-   */
-  public String getPathExactString() {
-    Preconditions.checkState(isPathExactMatch());
-    return pathExactMatchPattern;
-  }
-
-  /**
-   * Returns the original URL pattern.
-   * 
-   * @return the original URL pattern.
-   */
-  public String getUrlPattern() {
-    return urlPattern;
-  }
-
-  // This is the master meta-regex. This is used both for parsing URL patterns
-  // and for parsing URLs
-  private static final String URL_METAPATTERN_STRING =
-      "\\A(\\^)?((?:([^/:$<]*)((?:(?::|(?::/))?\\Z)|(?:://)))?" +
-    // ___1_____2a__3_________4b__c____d____________e
-      "(?:([^/:@]*)@)?([^/:<]*)?(?::([^/<]*))?)(/|(?:</>))?(?:(.*?)(\\Z|\\$)?)?\\Z"
-    // f__5___________6_________g___7__________8__h________i__9____0
-  ;
-
-  // Groups: (capturing groups are numbered, non-capturing are lettered)
-  // 1 anchor (^)
-  // 2 protocol + authority (not including /)
-  // a protocol + ((nothing or : or :/ followed by end of pattern) or ::/)
-  // 3 protocol
-  // 4 protocol separator ((nothing or : or :/ followed by end of pattern) or
-  // ::/)
-  // b nothing or : or :/ followed by end of pattern
-  // c : or :/
-  // d :/
-  // e ::/
-  // f userinfo + @
-  // 5 userinfo
-  // 6 host
-  // g : + port
-  // 7 port
-  // 8 slash (after authority) (could be a slash or "</>")
-  // h </>
-  // i file + anchor
-  // 9 file
-  // 10 anchor ($)
-  
-  // This Pattern is package visible so it can be used by AnalyzedUrl
-  static final Pattern URL_METAPATTERN = Pattern.compile(URL_METAPATTERN_STRING);
-
-  // As above, the enum is package visible so it can be used by AnalyzedUrl
-  // Note: if you change the master regex, you should change this enum to match
-  static enum MetaRegexGroup {
-    LEFT_ANCHOR(1), PROTOCOL_AUTHORITY(2), PROTOCOL(3), PROTOCOL_SEPARATOR(4), USERINFO(5),
-    HOST(6), PORT(7), SLASH_AFTER_AUTHORITY(8), FILE(9), RIGHT_ANCHOR(10);
-    private int n;
-
-    MetaRegexGroup(int n) {
-      this.n = n;
-    }
-
-    int intValue() {
-      return n;
-    }
-  }
-
-  // This static helper is also shared with the AnalyzedUrl
-  static String getGroup(Matcher m, MetaRegexGroup g) {
-    String s = m.group(g.intValue());
-    return (s == null) ? "" : s;
-  }
-
-  private static class ParsedUrlPatternBuilder {
-
-    public String urlPattern;
-    public String urlRegex;
-
-    public boolean hostPathType;
-    public String hostRegex;
-
-    public String pathRegex;
-    public boolean pathExactMatch;
-    public String pathExactMatchPattern;
-
-    public boolean prefixPathMatch;
-    public String prefixPathMatchPattern;
-
-    ParsedUrlPatternBuilder(String urlPattern) {
-      checkPatternValidity(urlPattern);
-      this.urlPattern = urlPattern;
-      analyze();
-    }
-
-    private void analyze() {
-      if (urlPattern.startsWith(CONTAINS_PATTERNS_METAPATTERN_PREFIX)) {
-        urlRegex =
-            Pattern.quote(urlPattern.substring(CONTAINS_PATTERNS_METAPATTERN_PREFIX.length()));
-        initNonHostPathPattern();
-        return;
-      }
-
-      if (urlPattern.startsWith(REGEXP_PATTERNS_METAPATTERN_PREFIX)) {
-        urlRegex = urlPattern.substring(REGEXP_PATTERNS_METAPATTERN_PREFIX.length());
-        initNonHostPathPattern();
-        return;
-      }
-
-      if (urlPattern.startsWith(REGEXPCASE_PATTERNS_METAPATTERN_PREFIX)) {
-        urlRegex = urlPattern.substring(REGEXPCASE_PATTERNS_METAPATTERN_PREFIX.length());
-        initNonHostPathPattern();
-        return;
-      }
-
-      if (urlPattern.startsWith(REGEXPIGNORECASE_PATTERNS_METAPATTERN_PREFIX)) {
-        urlRegex =
-            "(?i:" + urlPattern.substring(REGEXPIGNORECASE_PATTERNS_METAPATTERN_PREFIX.length())
-                + ")";
-        initNonHostPathPattern();
-        return;
-      }
-
-      initHostPathPattern();
-
-      if (isNullOrEmpty(urlPattern)) {
-        prefixPathMatch = true;
-        return;
-      }
-      if (testForAndHandleNoSlashSuffixPattern()) {
-        return;
-      }
-      Matcher m = URL_METAPATTERN.matcher(urlPattern);
-      Preconditions.checkArgument(m.find(), "problem parsing urlpattern: " + urlPattern);
-      urlRegex = buildUrlRegex(m);
-      pathRegex = buildPathRegex(m);
-      hostRegex = buildHostRegex(m);
-    }
-
-    private void initNonHostPathPattern() {
-      hostPathType = false;
-      pathRegex = null;
-      hostRegex = null;
-      pathExactMatch = false;
-      pathExactMatchPattern = null;
-      prefixPathMatch = false;
-      prefixPathMatchPattern = null;
-    }
-
-    private void initHostPathPattern() {
-      hostPathType = true;
-      urlRegex = "";
-      pathRegex = "";
-      hostRegex = "";
-      pathExactMatch = false;
-      pathExactMatchPattern = null;
-      prefixPathMatch = false;
-      prefixPathMatchPattern = "/";
-    }
-
-    // A suffix pattern (ends in $) that has no slash just doesn't parse well
-    // with
-    // the metapattern. So we use a special pattern for this case.
-    private boolean testForAndHandleNoSlashSuffixPattern() {
-      Matcher m = NO_SLASH_SUFFIX_PATTERN.matcher(urlPattern);
-      if (!m.find()) {
-        return false;
-      }
-      urlRegex = Pattern.quote(m.group(1)) + OUTPUT_RIGHT_ANCHOR_PATTERN_STRING;
-      pathRegex = urlRegex;
-      hostRegex = "";
-      pathExactMatch = false;
-      pathExactMatchPattern = null;
-      prefixPathMatch = false;
-      prefixPathMatchPattern = null;
-      return true;
-    }
-
-    // suffix patterns that contain no slash jam up my master meta-regex: the
-    // string before the $ gets put in the wrong capturing group. I fought with
-    // it
-    // a while but then bailed and just made a special meta-regex for them
-    private static final String NO_SLASH_SUFFIX_PATTERN_STRING = "\\A([^/]*)\\$\\Z";
-    private static final Pattern NO_SLASH_SUFFIX_PATTERN =
-        Pattern.compile(NO_SLASH_SUFFIX_PATTERN_STRING);
-
-    private static final String CONTAINS_PATTERNS_METAPATTERN_PREFIX = "contains:";
-
-    private static final String REGEXP_PATTERNS_METAPATTERN_PREFIX = "regexp:";
-
-    private static final String REGEXPCASE_PATTERNS_METAPATTERN_PREFIX = "regexpCase:";
-
-    private static final String REGEXPIGNORECASE_PATTERNS_METAPATTERN_PREFIX = "regexpIgnoreCase:";
-
-    private static final String UNSUPPORTED_PATTERNS_METAPATTERN_STRING = "\\A(?:(www\\?:)|(-))";
-    private static final Pattern UNSUPPORTED_PATTERNS_METAPATTERN =
-        Pattern.compile(UNSUPPORTED_PATTERNS_METAPATTERN_STRING);
-
-    private static final String OUTPUT_RIGHT_ANCHOR_PATTERN_STRING = "\\Z";
-    private static final String OUTPUT_LEFT_ANCHOR_PATTERN_STRING = "\\A";
-
-    private static final String OUTPUT_SLASH = "/";
-    private static final String OUTPUT_ANY_OR_NO_PORT_PATTERN = "(\\:[^/]*)?";
-    private static final String OUTPUT_ANY_PORT_PATTERN = "\\:[^/]*";
-
-    private static boolean isNullOrEmpty(String s) {
-      return (s == null || s.length() < 1);
-    }
-
-    // These helper functions whose names match buildSOMETHINGPattern build a
-    // regex to match the SOMETHING in their names. They should be usable,
-    // appropriately quoted regexes
-    private static String buildProtocolUserinfoHostPattern(Matcher m) {
-      StringBuilder sb = new StringBuilder();
-      sb.append(getGroup(m, MetaRegexGroup.PROTOCOL));
-      sb.append(getGroup(m, MetaRegexGroup.PROTOCOL_SEPARATOR));
-      String userInfo = getGroup(m, MetaRegexGroup.USERINFO);
-      if (!isNullOrEmpty(userInfo)) {
-        sb.append(userInfo);
-        sb.append("@");
-      }
-      sb.append(getGroup(m, MetaRegexGroup.HOST));
-      String unquotedPattern = sb.toString();
-      return isNullOrEmpty(unquotedPattern) ? "" : Pattern.quote(unquotedPattern);
-    }
-
-    // port is tricky because the absence of a port in a pattern should match
-    // any
-    // specific port in a target
-    private static String buildPortPattern(Matcher m) {
-      StringBuilder sb = new StringBuilder();
-      String port = getGroup(m, MetaRegexGroup.PORT);
-      if (isNullOrEmpty(port)) {
-        // port was empty - match any port - default or explicit
-        sb.append(OUTPUT_ANY_OR_NO_PORT_PATTERN);
-      } else {
-        if (port.equals("*")) {
-          // port was explicitly "*" - match any explicitly specified port
-          sb.append(OUTPUT_ANY_PORT_PATTERN);
-        } else {
-          // port was explicit and not "*" - match only that port
-          sb.append("\\:");
-          sb.append(Pattern.quote(port));
-        }
-      }
-      return sb.toString();
-    }
-
-    private static String buildUnquotedFilePattern(Matcher m) {
-      return getGroup(m, MetaRegexGroup.FILE);
-    }
-
-    private static String buildQuotedFilePattern(Matcher m) {
-      String unquotedPattern = buildUnquotedFilePattern(m);
-      return isNullOrEmpty(unquotedPattern) ? "" : Pattern.quote(unquotedPattern);
-    }
-
-    // the helper functions whose names match buildSOMETHINGRegex each build one
-    // of the three public regexes: the urlRegex, the protocolAuthorityRegex and
-    // the fileRegex.
-
-    // The main reason that the urlRegex is not simply the concatenation of the
-    // protocolAuthorityRegex and the fileRegex is the anchors. Both for
-    // correctness and efficiency, we want to use anchors only where
-    // appropriate:
-    // using ^A.*foo is considerably slower than just using foo.
-    private String buildUrlRegex(Matcher m) {
-      StringBuilder sb = new StringBuilder();
-      String leftAnchor = getGroup(m, MetaRegexGroup.LEFT_ANCHOR);
-      String protocolUserinfoHostPattern = buildProtocolUserinfoHostPattern(m);
-      String portPattern = buildPortPattern(m);
-      String slashAfterAuthority = getGroup(m, MetaRegexGroup.SLASH_AFTER_AUTHORITY);
-      String filePattern = buildQuotedFilePattern(m);
-      String rightAnchor = getGroup(m, MetaRegexGroup.RIGHT_ANCHOR);
-      // prefix patterns need to be handled specially
-      if (!isNullOrEmpty(leftAnchor)) {
-        sb.append(OUTPUT_LEFT_ANCHOR_PATTERN_STRING);
-      }
-      if (!isNullOrEmpty(protocolUserinfoHostPattern)) {
-        sb.append(protocolUserinfoHostPattern);
-      }
-      if (!isNullOrEmpty(portPattern)) {
-        if (sb.length() > 0) {
-          sb.append(portPattern);
-        }
-      }
-      if (!isNullOrEmpty(slashAfterAuthority)) {
-        if ("</>".equals(slashAfterAuthority)) {
-          if (sb.length() < 1) {
-            sb.append(OUTPUT_LEFT_ANCHOR_PATTERN_STRING);
-            sb.append("[^/]*//[^/]*");
-          }
-        }
-        sb.append(OUTPUT_SLASH);
-      }
-      if (!isNullOrEmpty(filePattern)) {
-        sb.append(filePattern);
-      }
-      if (!isNullOrEmpty(rightAnchor)) {
-        sb.append(rightAnchor);
-      }
-      return sb.toString();
-    }
-
-    private String buildHostRegex(Matcher m) {
-      StringBuilder sb = new StringBuilder();
-      String leftAnchor = getGroup(m, MetaRegexGroup.LEFT_ANCHOR);
-      String protocolUserinfoHostPattern = buildProtocolUserinfoHostPattern(m);
-      String portPattern = buildPortPattern(m);
-      String slashAfterAuthority = getGroup(m, MetaRegexGroup.SLASH_AFTER_AUTHORITY);
-      // prefix patterns need to be handled specially
-      if (!isNullOrEmpty(leftAnchor)) {
-        sb.append(OUTPUT_LEFT_ANCHOR_PATTERN_STRING);
-      }
-      if (!isNullOrEmpty(protocolUserinfoHostPattern)) {
-        sb.append(protocolUserinfoHostPattern);
-      }
-      if (!isNullOrEmpty(portPattern)) {
-        sb.append(portPattern);
-      }
-      if (!isNullOrEmpty(slashAfterAuthority)) {
-        sb.append(OUTPUT_SLASH);
-      }
-      return sb.toString();
-    }
-
-    // We expect that, in practice, the fileRegex will be used much more often
-    // than the protocolAuthority regex (there will probably be a hashtable for
-    // the protocol-authority portion), so we really want to makes sure that the
-    // fileRegexes are simple prefix matches, as often as possible.
-    private String buildPathRegex(Matcher m) {
-      boolean hasLeftAnchor = false;
-      boolean hasRightAnchor = false;
-      StringBuilder sb = new StringBuilder();
-      String protocolAuthority = getGroup(m, MetaRegexGroup.PROTOCOL_AUTHORITY);
-      String slashAfterAuthority = getGroup(m, MetaRegexGroup.SLASH_AFTER_AUTHORITY);
-      String unquotedFilePattern = buildUnquotedFilePattern(m);
-      String rightAnchor = getGroup(m, MetaRegexGroup.RIGHT_ANCHOR);
-      // two conditions for this being an prefix pattern:
-      // either there was a protocolAuthority OR there was a </>
-      // slashAfterAuthority
-      if (!isNullOrEmpty(protocolAuthority) || "</>".equals(slashAfterAuthority)) {
-        hasLeftAnchor = true;
-        sb.append(OUTPUT_LEFT_ANCHOR_PATTERN_STRING);
-      }
-      if (!isNullOrEmpty(slashAfterAuthority)) {
-        sb.append(OUTPUT_SLASH);
-      }
-      sb.append(Pattern.quote(unquotedFilePattern));
-      if (!isNullOrEmpty(rightAnchor)) {
-        hasRightAnchor = true;
-        sb.append(OUTPUT_RIGHT_ANCHOR_PATTERN_STRING);
-      }
-      if (hasLeftAnchor) {
-        if (hasRightAnchor) {
-          this.pathExactMatch = true;
-          this.pathExactMatchPattern = "/" + unquotedFilePattern;
-          this.prefixPathMatch = false;
-          this.prefixPathMatchPattern = null;
-        } else {
-          this.pathExactMatch = false;
-          this.pathExactMatchPattern = null;
-          this.prefixPathMatch = true;
-          this.prefixPathMatchPattern = "/" + unquotedFilePattern;
-        }
-      }
-      return sb.toString();
-    }
-
-    private static void checkPatternValidity(String s) {
-      Preconditions.checkNotNull(s);
-      Matcher m = UNSUPPORTED_PATTERNS_METAPATTERN.matcher(s);
-      Preconditions.checkArgument(!m.find(), "unsupported urlpattern: " + s);
-    }
-  }
-}
diff --git a/src/com/google/common/util/concurrent/BoundedExecutorService.java b/src/com/google/common/util/concurrent/BoundedExecutorService.java
deleted file mode 100644
index 12dd84a..0000000
--- a/src/com/google/common/util/concurrent/BoundedExecutorService.java
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.common.util.concurrent;
-
-import java.util.List;
-import java.util.concurrent.*;
-
-/**
- * Trash class to allow code to compile unmodified.
- */
-public class BoundedExecutorService extends AbstractExecutorService {
-  public BoundedExecutorService(Object ... params) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean awaitTermination(long timeout, TimeUnit unit) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isShutdown() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public boolean isTerminated() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void shutdown() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public List<Runnable> shutdownNow() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void execute(Runnable command) {
-    throw new UnsupportedOperationException();
-  }
-}
diff --git a/src/com/google/enterprise/adaptor/CronScheduler.java b/src/com/google/enterprise/adaptor/CronScheduler.java
index 1cf3335..f0f260a 100644
--- a/src/com/google/enterprise/adaptor/CronScheduler.java
+++ b/src/com/google/enterprise/adaptor/CronScheduler.java
@@ -163,7 +163,8 @@
   }
 
   private static class CronPattern {
-    private static final List<Field> FIELDS = Arrays.asList(Field.values());
+    private static final List<Field> FIELDS
+        = Collections.unmodifiableList(Arrays.asList(Field.values()));
 
     private static enum Field {
       MINUTE(0, 60, Calendar.MINUTE, 0),
@@ -216,27 +217,46 @@
     // day of month: 0-30, 0 is 1st day of month.
     // month: 0-11, 0 in January.
     // day of week: 0-6, 0 is Sunday.
-    private final List<BitSet> fields;
+    // null for any value implies wildcard
+    private final EnumMap<Field, BitSet> fields;
 
-    private CronPattern(List<BitSet> fields) {
+    private CronPattern(EnumMap<Field, BitSet> fields) {
       this.fields = fields;
     }
 
     public boolean matches(Date date, TimeZone timeZone) {
       GregorianCalendar calendar = new GregorianCalendar(timeZone);
       calendar.setTime(date);
-      for (int i = 0; i < FIELDS.size(); i++) {
-        Field field = FIELDS.get(i);
-        if (!fields.get(i).get(field.calendarToIndex(calendar))) {
-          return false;
-        }
+      boolean dayMatches;
+      if (fields.get(Field.DAY_OF_MONTH) != null
+          && fields.get(Field.DAY_OF_WEEK) != null) {
+        // Both day of month and day of week are restricted, so we OR the two
+        // instead of the typical AND. This is a special case of the cron
+        // format since both fields restrict the day.
+        dayMatches = matches(Field.DAY_OF_MONTH, calendar)
+            || matches(Field.DAY_OF_WEEK, calendar);
+      } else {
+        dayMatches = matches(Field.DAY_OF_MONTH, calendar)
+            && matches(Field.DAY_OF_WEEK, calendar);
       }
-      return true;
+      return dayMatches
+          && matches(Field.MINUTE, calendar)
+          && matches(Field.HOUR, calendar)
+          && matches(Field.MONTH, calendar);
+    }
+
+    private boolean matches(Field field, Calendar calendar) {
+      BitSet bitset = fields.get(field);
+      if (bitset == null) {
+        // Wildcard.
+        return true;
+      }
+      return bitset.get(field.calendarToIndex(calendar));
     }
 
     @Override
     public String toString() {
-      return "" + fields;
+      return "" + fields.values();
     }
 
     public static CronPattern create(String timeSpecification)
@@ -248,10 +268,15 @@
             "Should have precisely 5 fields: "
             + "minute, hour, day of month, month, day of week");
       }
-      List<BitSet> fields = new ArrayList<BitSet>(FIELDS.size());
-      for (int i = 0; i < FIELDS.size(); i++) {
-        String stringField = stringFields[i];
-        Field fieldType = FIELDS.get(i);
+      EnumMap<Field, BitSet> fields = new EnumMap<Field, BitSet>(Field.class);
+      for (Field fieldType : FIELDS) {
+        String stringField = stringFields[fieldType.ordinal()];
+        if ("*".equals(stringField)) {
+          // Signal wildcard. Semantics of day of week and day of month vary
+          // based on raw wildcard vs any other value.
+          fields.put(fieldType, null);
+          continue;
+        }
         BitSet set = new BitSet(fieldType.numValues());
         for (String element : stringField.split(",", -1)) {
           int step = 1;
@@ -282,7 +307,7 @@
             }
           }
         }
-        fields.add(set);
+        fields.put(fieldType, set);
       }
       return new CronPattern(fields);
     }
diff --git a/src/com/google/enterprise/adaptor/HttpClientAdapter.java b/src/com/google/enterprise/adaptor/HttpClientAdapter.java
index 2b56d3e..ae46b16 100644
--- a/src/com/google/enterprise/adaptor/HttpClientAdapter.java
+++ b/src/com/google/enterprise/adaptor/HttpClientAdapter.java
@@ -15,8 +15,6 @@
 package com.google.enterprise.adaptor;
 
 import com.google.common.collect.ListMultimap;
-import com.google.enterprise.secmgr.common.CookieStore;
-import com.google.enterprise.secmgr.common.GCookie;
 import com.google.enterprise.secmgr.http.HttpClientInterface;
 import com.google.enterprise.secmgr.http.HttpExchange;
 
@@ -39,16 +37,6 @@
   private static final String POST_ENCODING = "UTF-8";
 
   @Override
-  public HttpExchange headExchange(URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange getExchange(URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
   public HttpExchange postExchange(URL url,
                                    ListMultimap<String, String> parameters) {
     HttpExchange exchange = new ClientExchange(url, "POST");
@@ -64,42 +52,6 @@
     return exchange;
   }
 
-  @Override
-  public HttpExchange newHttpExchange(URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Connection getConnection(URL url) throws IOException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange headExchange(Connection connection, URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange getExchange(Connection connection, URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange postExchange(Connection connection, URL url,
-                                   ListMultimap<String, String> parameters) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange newHttpExchange(Connection connection, URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setRequestTimeoutMillis(int millisec) {
-    throw new UnsupportedOperationException();
-  }
-
   private static class ClientExchange implements HttpExchange {
     private final URL url;
     private final String method;
@@ -182,16 +134,6 @@
       return conn.getRequestProperty(headerName);
     }
 
-    @Override
-    public void addCookies(Iterable<GCookie> cookies) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CookieStore getCookies() {
-      throw new UnsupportedOperationException();
-    }
-
     /** Does not copy provided byte array. */
     @Override
     public void setRequestBody(byte[] byteArrayRequestEntity) {
diff --git a/src/com/google/enterprise/adaptor/SecurityManagerConfig.java b/src/com/google/enterprise/adaptor/SecurityManagerConfig.java
index 813825f..d714a86 100644
--- a/src/com/google/enterprise/adaptor/SecurityManagerConfig.java
+++ b/src/com/google/enterprise/adaptor/SecurityManagerConfig.java
@@ -14,11 +14,8 @@
 
 package com.google.enterprise.adaptor;
 
-import com.google.enterprise.secmgr.authncontroller.AuthnGuiceModule;
-import com.google.enterprise.secmgr.common.GCookie;
-import com.google.enterprise.secmgr.config.ConfigModule;
+import com.google.enterprise.secmgr.authncontroller.ExportedState;
 import com.google.enterprise.secmgr.config.ConfigSingleton;
-import com.google.enterprise.secmgr.identity.CredentialModule;
 import com.google.gson.GsonBuilder;
 
 class SecurityManagerConfig {
@@ -27,10 +24,7 @@
         new ConfigSingleton.GsonRegistrations() {
           @Override
           public void register(GsonBuilder builder) {
-            AuthnGuiceModule.registerTypeAdapters(builder);
-            ConfigModule.registerTypeAdapters(builder);
-            CredentialModule.registerTypeAdapters(builder);
-            GCookie.registerTypeAdapters(builder);
+            ExportedState.registerTypeAdapters(builder);
           }
         });
   }
diff --git a/src/com/google/enterprise/secmgr/authncontroller/AuthnGuiceModule.java b/src/com/google/enterprise/secmgr/authncontroller/AuthnGuiceModule.java
deleted file mode 100644
index eac2824..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/AuthnGuiceModule.java
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.gson.GsonBuilder;
-/*import com.google.inject.AbstractModule;*/
-
-/**
- * Guice configuration for this package.
- */
-public final class AuthnGuiceModule /*extends AbstractModule*/ {
-
-  /*@Override
-  protected void configure() {
-    bind(AuthnController.class);
-    bind(AuthnSessionManager.class).to(AuthnSessionManagerImpl.class);
-    requestStaticInjection(AuthnSession.class);
-  }*/
-
-  public static void registerTypeAdapters(GsonBuilder builder) {
-    AuthnSessionState.registerTypeAdapters(builder);
-    ExportedState.registerTypeAdapters(builder);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/authncontroller/AuthnSessionState.java b/src/com/google/enterprise/secmgr/authncontroller/AuthnSessionState.java
deleted file mode 100644
index b0d513f..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/AuthnSessionState.java
+++ /dev/null
@@ -1,858 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.HashMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.ImmutableSetMultimap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.common.collect.SetMultimap;
-import com.google.enterprise.secmgr.common.Chain;
-import com.google.enterprise.secmgr.common.CookieStore;
-import com.google.enterprise.secmgr.common.GCookie;
-import com.google.enterprise.secmgr.common.SecurityManagerUtil;
-import com.google.enterprise.secmgr.config.AuthnAuthority;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
-import com.google.enterprise.secmgr.config.CredentialGroup;
-import com.google.enterprise.secmgr.identity.AbstractCredential;
-import com.google.enterprise.secmgr.identity.Credential;
-import com.google.enterprise.secmgr.identity.Verification;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * A representation of the state stored in an authentication session.  This is
- * not the AuthnState that's used to keep track of the what the controller is
- * doing; this is the credentials gathered by the controller.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class AuthnSessionState {
-
-  /**
-   * The possible instruction operations supported here.
-   */
-  public static enum Operation {
-    ADD_COOKIE(GCookie.class),
-    ADD_CREDENTIAL(Credential.class),
-    ADD_VERIFICATION(Verification.class),
-    REMOVE_COOKIE(GCookie.class),
-    REMOVE_CREDENTIAL(Credential.class),
-    REMOVE_VERIFICATION(Verification.class);
-
-    @Nonnull private final Class<?> operandClass;
-
-    private Operation(Class<?> operandClass) {
-      Preconditions.checkNotNull(operandClass);
-      this.operandClass = operandClass;
-    }
-
-    @CheckReturnValue
-    @Nonnull
-    public Class<?> getOperandClass() {
-      return operandClass;
-    }
-  }
-
-  private static final AuthnSessionState EMPTY = new AuthnSessionState(Chain.<Instruction>empty());
-
-  @Nonnull private final Chain<Instruction> instructions;
-
-  private AuthnSessionState(Chain<Instruction> instructions) {
-    Preconditions.checkNotNull(instructions);
-    this.instructions = instructions;
-  }
-
-  /**
-   * Gets an empty session state.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static AuthnSessionState empty() {
-    return EMPTY;
-  }
-
-  /**
-   * Gets a new session state with only the given verification.
-   *
-   * @param authority The authority that performed the verification process.
-   * @param verification The verification that the state will hold.
-   * @return A new state with that verification.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static AuthnSessionState of(AuthnAuthority authority, Verification verification) {
-    return empty().addVerification(authority, verification);
-  }
-
-  @VisibleForTesting
-  static AuthnSessionState of(Iterable<Instruction> instructions) {
-    return new AuthnSessionState(Chain.copyOf(instructions));
-  }
-
-  @VisibleForTesting
-  List<Instruction> getInstructions() {
-    return instructions.toList();
-  }
-
-  /**
-   * Is this state object empty?
-   *
-   * @return True only if there are no elements in this state.
-   */
-  @CheckReturnValue
-  public boolean isEmpty() {
-    return instructions.isEmpty();
-  }
-
-  /**
-   * Unit testing relies on this; it's not used in production.
-   */
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnSessionState)) { return false; }
-    AuthnSessionState other = (AuthnSessionState) object;
-    return Objects.equal(instructions, other.instructions);
-  }
-
-  /**
-   * Unit testing relies on this; it's not used in production.
-   */
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(instructions);
-  }
-
-  /**
-   * Unit testing uses this for failure reporting; it's not used in production.
-   */
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    for (Instruction instruction : getInstructions()) {
-      builder.append("  ");
-      builder.append(instruction);
-      builder.append("\n");
-    }
-    return builder.toString();
-  }
-
-  /**
-   * Appends some state to this state.
-   *
-   * @param delta The state to append
-   * @return A new state with that state appended.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState add(AuthnSessionState delta) {
-    return new AuthnSessionState(instructions.addAll(delta.getInstructions()));
-  }
-
-  /**
-   * Gets a session state that represents the delta between this state and a
-   * given one.  For a given ancestor state {@code A}, it is always true that
-   * {@code this.equals(A.add(this.getDelta(A)))}.
-   *
-   * @param ancestor The ancestor state to use as a reference.
-   * @return A new state with instructions that have been added since the
-   *     ancestor.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState getDelta(AuthnSessionState ancestor) {
-    return AuthnSessionState.of(instructions.toList(ancestor.instructions));
-  }
-
-  @CheckReturnValue
-  private AuthnSessionState addInstruction(Instruction instruction) {
-    Preconditions.checkNotNull(instruction);
-    return new AuthnSessionState(instructions.add(instruction));
-  }
-
-  /**
-   * Adds a cookie to this state.
-   *
-   * @param authority The authority from which the cookie was received.
-   * @param cookie The cookie to be added.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState addCookie(AuthnAuthority authority, GCookie cookie) {
-    return addInstruction(Instruction.make(Operation.ADD_COOKIE, authority, cookie));
-  }
-
-  /**
-   * Adds some cookies to this state.
-   *
-   * @param authority The authority from which the cookie was received.
-   * @param cookies The cookies to be added.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState addCookies(AuthnAuthority authority, Iterable<GCookie> cookies) {
-    AuthnSessionState state = this;
-    for (GCookie cookie : cookies) {
-      state = state.addCookie(authority, cookie);
-    }
-    return state;
-  }
-
-  /**
-   * Removes a cookie from this state.
-   *
-   * @param authority The authority from which the cookie was originally received.
-   * @param cookie The cookie to be removed.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState removeCookie(AuthnAuthority authority, GCookie cookie) {
-    return addInstruction(Instruction.make(Operation.REMOVE_COOKIE, authority, cookie));
-  }
-
-  /**
-   * Removes some cookies from this state.
-   *
-   * @param authority The authority from which the cookie was received.
-   * @param cookies The cookies to be removed.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState removeCookies(AuthnAuthority authority, Iterable<GCookie> cookies) {
-    AuthnSessionState state = this;
-    for (GCookie cookie : cookies) {
-      state = state.removeCookie(authority, cookie);
-    }
-    return state;
-  }
-
-  /**
-   * Adds a credential to this state.
-   *
-   * @param authority The authority from which the credential was received.
-   * @param credential The credential to be added.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState addCredential(AuthnAuthority authority, Credential credential) {
-    return addInstruction(Instruction.make(Operation.ADD_CREDENTIAL, authority, credential));
-  }
-
-  /**
-   * Adds some credentials to this state.
-   *
-   * @param authority The authority from which the cookie was received.
-   * @param credentials The credentials to be added.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState addCredentials(AuthnAuthority authority,
-      Iterable<Credential> credentials) {
-    AuthnSessionState state = this;
-    for (Credential credential : credentials) {
-      state = state.addCredential(authority, credential);
-    }
-    return state;
-  }
-
-  /**
-   * Removes a credential from this state.
-   *
-   * @param authority The authority from which the credential was originally received.
-   * @param credential The credential to be removed.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState removeCredential(AuthnAuthority authority,
-      Credential credential) {
-    return addInstruction(Instruction.make(Operation.REMOVE_CREDENTIAL, authority, credential));
-  }
-
-  /**
-   * Adds a verification to this state.
-   *
-   * @param authority The authority that performed the verification process.
-   * @param verification The verification to be added.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState addVerification(AuthnAuthority authority, Verification verification) {
-    return addInstruction(Instruction.make(Operation.ADD_VERIFICATION, authority, verification));
-  }
-
-  /**
-   * Adds some verifications to this state.
-   *
-   * @param authority The authority that performed the verification process.
-   * @param verifications The verifications to be added.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState addVerifications(AuthnAuthority authority,
-      Iterable<Verification> verifications) {
-    AuthnSessionState state = this;
-    for (Verification verification : verifications) {
-      state = state.addVerification(authority, verification);
-    }
-    return state;
-  }
-
-  /**
-   * Removes a verification from this state.
-   *
-   * @param authority The authority that performed the verification process.
-   * @param verification The verification to be removed.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState removeVerification(AuthnAuthority authority, Verification verification) {
-    return addInstruction(Instruction.make(Operation.REMOVE_VERIFICATION, authority, verification));
-  }
-
-  /**
-   * Removes some verifications from this state.
-   *
-   * @param authority The authority that performed the verification process.
-   * @param verifications The verifications to be removed.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState removeVerifications(AuthnAuthority authority,
-      Iterable<Verification> verifications) {
-    AuthnSessionState state = this;
-    for (Verification verification : verifications) {
-      state = state.removeVerification(authority, verification);
-    }
-    return state;
-  }
-
-  /**
-   * Computes a summary of this state's contents.
-   *
-   * @param credentialGroups The credential groups associated with this session.
-   * @return An immutable summary of the state's contents.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Summary computeSummary(Iterable<CredentialGroup> credentialGroups) {
-    return evolveSummary(new Evolver(credentialGroups));
-  }
-
-  /**
-   * Computes a summary by extending a given summary with this state's contents.
-   *
-   * @param summary The summary to be extended.
-   * @return An immutable extended summary.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Summary evolveSummary(Summary summary) {
-    return evolveSummary(summary.evolve());
-  }
-
-  private Summary evolveSummary(Evolver evolver) {
-    for (Instruction instruction : getInstructions()) {
-      AuthnAuthority authority = instruction.getAuthority();
-      Object operand = instruction.getOperand();
-      switch (instruction.getOperation()) {
-        case ADD_COOKIE:
-          evolver.addCookie(authority, (GCookie) operand);
-          break;
-        case REMOVE_COOKIE:
-          evolver.removeCookie(authority, (GCookie) operand);
-          break;
-        case ADD_CREDENTIAL:
-          evolver.addCredential(authority, (Credential) operand);
-          break;
-        case REMOVE_CREDENTIAL:
-          evolver.removeCredential(authority, (Credential) operand);
-          break;
-        case ADD_VERIFICATION:
-          evolver.addVerification(authority, (Verification) operand);
-          break;
-        case REMOVE_VERIFICATION:
-          evolver.removeVerification(authority, (Verification) operand);
-          break;
-        default:
-          throw new IllegalStateException("Unknown instruction operation: "
-              + instruction.getOperation());
-      }
-    }
-    return evolver.getSummary();
-  }
-
-  @NotThreadSafe
-  @ParametersAreNonnullByDefault
-  private static final class Evolver {
-    @Nonnull final ImmutableList<CredentialGroup> credentialGroups;
-    @Nonnull final Map<AuthnAuthority, CookieStore> cookiesMap;
-    @Nonnull final SetMultimap<AuthnAuthority, Credential> credentialsMap;
-    @Nonnull final Map<AuthnAuthority, Verification> verificationsMap;
-
-    Evolver(Iterable<CredentialGroup> credentialGroups) {
-      this.credentialGroups = ImmutableList.copyOf(credentialGroups);
-      cookiesMap = Maps.<AuthnAuthority, CookieStore>newHashMap();
-      credentialsMap = HashMultimap.<AuthnAuthority, Credential>create();
-      verificationsMap = Maps.<AuthnAuthority, Verification>newHashMap();
-    }
-
-    Evolver(ImmutableList<CredentialGroup> credentialGroups,
-        ImmutableMap<AuthnAuthority, ImmutableSet<GCookie>> cookiesMap,
-        ImmutableSetMultimap<AuthnAuthority, Credential> credentialsMap,
-        ImmutableMap<AuthnAuthority, Verification> verificationsMap) {
-      this.credentialGroups = credentialGroups;
-      this.cookiesMap = thawCookiesMap(cookiesMap);
-      this.credentialsMap = HashMultimap.create(credentialsMap);
-      this.verificationsMap = Maps.newHashMap(verificationsMap);
-    }
-
-    static Map<AuthnAuthority, CookieStore> thawCookiesMap(
-        ImmutableMap<AuthnAuthority, ImmutableSet<GCookie>> cookiesMap) {
-      Map<AuthnAuthority, CookieStore> result = Maps.newHashMap();
-      for (Map.Entry<AuthnAuthority, ImmutableSet<GCookie>> entry : cookiesMap.entrySet()) {
-        CookieStore cookies = GCookie.makeStore();
-        cookies.addAll(entry.getValue());
-        result.put(entry.getKey(), cookies);
-      }
-      return result;
-    }
-
-    Summary getSummary() {
-      return new Summary(credentialGroups, freezeCookiesMap(),
-          ImmutableSetMultimap.copyOf(credentialsMap), ImmutableMap.copyOf(verificationsMap));
-    }
-
-    ImmutableMap<AuthnAuthority, ImmutableSet<GCookie>> freezeCookiesMap() {
-      ImmutableMap.Builder<AuthnAuthority, ImmutableSet<GCookie>> builder = ImmutableMap.builder();
-      for (Map.Entry<AuthnAuthority, CookieStore> entry : cookiesMap.entrySet()) {
-        builder.put(entry.getKey(), ImmutableSet.copyOf(entry.getValue()));
-      }
-      return builder.build();
-    }
-
-    void addCookie(AuthnAuthority authority, GCookie cookie) {
-      getCookies(authority).add(cookie);
-    }
-
-    void removeCookie(AuthnAuthority authority, GCookie cookie) {
-      getCookies(authority).remove(cookie);
-    }
-
-    CookieStore getCookies(AuthnAuthority authority) {
-      CookieStore cookies = cookiesMap.get(authority);
-      if (cookies == null) {
-        cookies = GCookie.makeStore();
-        cookiesMap.put(authority, cookies);
-      }
-      return cookies;
-    }
-
-    void addCredential(AuthnAuthority authority, Credential credential) {
-      AuthnAuthority cgAuthority = getCredGroupAuthority(authority);
-      if (!credentialsMap.containsEntry(cgAuthority, credential)) {
-        Iterable<Credential> removed
-            = SecurityManagerUtil.removeInPlace(credentialsMap.get(cgAuthority),
-                AbstractCredential.getTypePredicate(credential.getClass()));
-        for (AuthnAuthority mechAuthority : getMechAuthorities(cgAuthority)) {
-          Verification verification = verificationsMap.get(mechAuthority);
-          if (verification != null && verification.containsAnyCredential(removed)) {
-            verificationsMap.remove(mechAuthority);
-          }
-        }
-        credentialsMap.put(cgAuthority, credential);
-      }
-    }
-
-    void removeCredential(AuthnAuthority authority, Credential credential) {
-      AuthnAuthority cgAuthority = getCredGroupAuthority(authority);
-      if (credentialsMap.containsEntry(cgAuthority, credential)) {
-        for (AuthnAuthority mechAuthority : getMechAuthorities(cgAuthority)) {
-          Verification verification = verificationsMap.get(mechAuthority);
-          if (verification != null && verification.containsCredential(credential)) {
-            verificationsMap.remove(mechAuthority);
-          }
-        }
-        credentialsMap.remove(cgAuthority, credential);
-      }
-    }
-
-    void addVerification(AuthnAuthority authority, Verification verification) {
-      verificationsMap.put(authority, verification);
-      for (Credential credential : verification.getCredentials()) {
-        addCredential(authority, credential);
-      }
-    }
-
-    void removeVerification(AuthnAuthority authority, Verification verification) {
-      if (verification.equals(verificationsMap.get(authority))) {
-        verificationsMap.remove(authority);
-      }
-    }
-
-    AuthnAuthority getCredGroupAuthority(AuthnAuthority authority) {
-      for (CredentialGroup credentialGroup : credentialGroups) {
-        for (AuthnMechanism mechanism : credentialGroup.getMechanisms()) {
-          if (authority.equals(mechanism.getAuthority())) {
-            return credentialGroup.getAuthority();
-          }
-        }
-      }
-      return authority;
-    }
-
-    Iterable<AuthnAuthority> getMechAuthorities(AuthnAuthority authority) {
-      for (CredentialGroup credentialGroup : credentialGroups) {
-        if (authority.equals(credentialGroup.getAuthority())) {
-          return Iterables.transform(credentialGroup.getMechanisms(),
-              AuthnMechanism.getAuthorityFunction());
-        }
-      }
-      return ImmutableList.of(authority);
-    }
-  }
-
-  /**
-   * The result of {@link #computeSummary}, this structure contains a summary of
-   * the session state as computed by executing the session-state's
-   * instructions.
-   */
-  @Immutable
-  @ParametersAreNonnullByDefault
-  public static final class Summary {
-    @Nonnull private final ImmutableList<CredentialGroup> credentialGroups;
-    @Nonnull private final ImmutableMap<AuthnAuthority, ImmutableSet<GCookie>> cookiesMap;
-    @Nonnull private final ImmutableSetMultimap<AuthnAuthority, Credential> credentialsMap;
-    @Nonnull private final ImmutableMap<AuthnAuthority, Verification> verificationsMap;
-
-    private Summary(ImmutableList<CredentialGroup> credentialGroups,
-        ImmutableMap<AuthnAuthority, ImmutableSet<GCookie>> cookiesMap,
-        ImmutableSetMultimap<AuthnAuthority, Credential> credentialsMap,
-        ImmutableMap<AuthnAuthority, Verification> verificationsMap) {
-      this.credentialGroups = credentialGroups;
-      this.cookiesMap = cookiesMap;
-      this.credentialsMap = credentialsMap;
-      this.verificationsMap = verificationsMap;
-    }
-
-    @CheckReturnValue
-    @Nonnull
-    private Evolver evolve() {
-      return new Evolver(credentialGroups, cookiesMap, credentialsMap, verificationsMap);
-    }
-
-    /**
-     * Gets the credential groups that were used to generate this summary.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableList<CredentialGroup> getCredentialGroups() {
-      return credentialGroups;
-    }
-
-    /**
-     * Gets all the cookies in this summary.
-     *
-     * @return An immutable map of the cookies for each authority.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableMap<AuthnAuthority, ImmutableSet<GCookie>> getCookiesMap() {
-      return cookiesMap;
-    }
-
-    /**
-     * Gets all the credentials in this summary.
-     *
-     * @return An immutable map of the credentials for each authority.
-     */
-    public ImmutableSetMultimap<AuthnAuthority, Credential> getCredentialsMap() {
-      return credentialsMap;
-    }
-
-    /**
-     * Gets all the verifications in this summary.
-     *
-     * @return An immutable map of the verifications for each authority.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableMap<AuthnAuthority, Verification> getVerificationsMap() {
-      return verificationsMap;
-    }
-
-    /**
-     * Gets the cookies in this summary for some specified authorities.
-     *
-     * @param predicate A predicate specifying the authorities to get cookies for.
-     * @return An immutable set of the cookies for the matching authorities.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableSet<GCookie> getCookies(Predicate<AuthnAuthority> predicate) {
-      ImmutableSet.Builder<GCookie> builder = ImmutableSet.builder();
-      for (Map.Entry<AuthnAuthority, ImmutableSet<GCookie>> entry : cookiesMap.entrySet()) {
-        if (predicate.apply(entry.getKey())) {
-          builder.addAll(entry.getValue());
-        }
-      }
-      return builder.build();
-    }
-
-    /**
-     * Gets the unexpired cookies in this summary for some specified authorities.
-     *
-     * @param predicate A predicate specifying the authorities to get cookies for.
-     * @param timeStamp A reference time to use for expiring cookies.
-     * @return An immutable set of the unexpired cookies for the matching authorities.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableSet<GCookie> getCookies(Predicate<AuthnAuthority> predicate, long timeStamp) {
-      ImmutableSet.Builder<GCookie> builder = ImmutableSet.builder();
-      for (Map.Entry<AuthnAuthority, ImmutableSet<GCookie>> entry : cookiesMap.entrySet()) {
-        if (predicate.apply(entry.getKey())) {
-          for (GCookie cookie : entry.getValue()) {
-            if (!cookie.isExpired(timeStamp)) {
-              builder.add(cookie);
-            }
-          }
-        }
-      }
-      return builder.build();
-    }
-
-    /**
-     * Gets the credentials in this summary for some specified authorities.
-     *
-     * @param predicate A predicate specifying the authorities to get credentials for.
-     * @return An immutable set of the credentials for the matching authorities.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableSet<Credential> getCredentials(Predicate<AuthnAuthority> predicate) {
-      ImmutableSet.Builder<Credential> builder = ImmutableSet.builder();
-      for (AuthnAuthority authority : credentialsMap.keySet()) {
-        if (predicate.apply(authority)) {
-          builder.addAll(credentialsMap.get(authority));
-        }
-      }
-      return builder.build();
-    }
-
-    /**
-     * Gets the verifications in this summary for some specified authorities.
-     *
-     * @param predicate A predicate specifying the authorities to get verifications for.
-     * @return An immutable set of the verifications for the matching authorities.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableSet<Verification> getVerifications(Predicate<AuthnAuthority> predicate) {
-      ImmutableSet.Builder<Verification> builder = ImmutableSet.builder();
-      for (Map.Entry<AuthnAuthority, Verification> entry : verificationsMap.entrySet()) {
-        if (predicate.apply(entry.getKey())) {
-          builder.add(entry.getValue());
-        }
-      }
-      return builder.build();
-    }
-
-    /**
-     * Gets the unexpired verifications in this summary for some specified authorities.
-     *
-     * @param predicate A predicate specifying the authorities to get verifications for.
-     * @param timeStamp A reference time to use for expiring verifications.
-     * @return An immutable set of the unexpired verifications for the matching authorities.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public ImmutableSet<Verification> getVerifications(Predicate<AuthnAuthority> predicate,
-        long timeStamp) {
-      ImmutableSet.Builder<Verification> builder = ImmutableSet.builder();
-      for (Map.Entry<AuthnAuthority, Verification> entry : verificationsMap.entrySet()) {
-        if (predicate.apply(entry.getKey())) {
-          Verification verification = entry.getValue();
-          if (!verification.hasExpired(timeStamp)) {
-            builder.add(verification);
-          }
-        }
-      }
-      return builder.build();
-    }
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnSessionState.class,
-        ProxyTypeAdapter.make(AuthnSessionState.class, LocalProxy.class));
-    builder.registerTypeAdapter(Instruction.class,
-        new Instruction.LocalTypeAdapter());
-  }
-
-  private static final class LocalProxy implements TypeProxy<AuthnSessionState> {
-    List<Instruction> instructions;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnSessionState state) {
-      instructions = state.getInstructions();
-    }
-
-    @Override
-    public AuthnSessionState build() {
-      return AuthnSessionState.of(instructions);
-    }
-  }
-
-  /**
-   * An instruction, consisting of an operation, an authority, and an operand.
-   */
-  @Immutable
-  @ParametersAreNonnullByDefault
-  public static final class Instruction {
-    @Nonnull private final Operation operation;
-    @Nonnull private final AuthnAuthority authority;
-    @Nonnull private final Object operand;
-
-    private Instruction(Operation operation, AuthnAuthority authority, Object operand) {
-      this.operation = operation;
-      this.authority = authority;
-      this.operand = operand;
-    }
-
-    @CheckReturnValue
-    @Nonnull
-    public static Instruction make(Operation operation, AuthnAuthority authority, Object operand) {
-      Preconditions.checkNotNull(authority);
-      Preconditions.checkArgument(operation.getOperandClass().isInstance(operand));
-      return new Instruction(operation, authority, operand);
-    }
-
-    @CheckReturnValue
-    @Nonnull
-    public Operation getOperation() {
-      return operation;
-    }
-
-    @CheckReturnValue
-    @Nonnull
-    public AuthnAuthority getAuthority() {
-      return authority;
-    }
-
-    @CheckReturnValue
-    @Nonnull
-    public Object getOperand() {
-      return operand;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-      if (object == this) { return true; }
-      if (!(object instanceof Instruction)) { return false; }
-      Instruction other = (Instruction) object;
-      return Objects.equal(getOperation(), other.getOperation())
-          && Objects.equal(getAuthority(), other.getAuthority())
-          && Objects.equal(getOperand(), other.getOperand());
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(getOperation(), getAuthority(), getOperand());
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder builder = new StringBuilder();
-      switch (operation) {
-        case ADD_COOKIE:
-        case ADD_CREDENTIAL:
-        case ADD_VERIFICATION:
-          builder.append("add to ");
-          break;
-        case REMOVE_COOKIE:
-        case REMOVE_CREDENTIAL:
-        case REMOVE_VERIFICATION:
-          builder.append("remove from ");
-          break;
-        default:
-          throw new IllegalStateException("Unknown operation: " + operation);
-      }
-      builder.append(authority);
-      builder.append(": ");
-      builder.append(operand);
-      return builder.toString();
-    }
-
-    private static final class LocalTypeAdapter
-        implements JsonSerializer<Instruction>, JsonDeserializer<Instruction> {
-      static final String KEY_OPERATION = "operation";
-      static final String KEY_AUTHORITY = "authority";
-      static final String KEY_OPERAND = "operand";
-
-      LocalTypeAdapter() {
-      }
-
-      @Override
-      public JsonElement serialize(Instruction instruction, Type type,
-          JsonSerializationContext context) {
-        JsonObject jo = new JsonObject();
-        Operation operation = instruction.getOperation();
-        jo.addProperty(KEY_OPERATION, operation.toString());
-        jo.add(KEY_AUTHORITY, context.serialize(instruction.getAuthority(), AuthnAuthority.class));
-        jo.add(KEY_OPERAND,
-            context.serialize(instruction.getOperand(), operation.getOperandClass()));
-        return jo;
-      }
-
-      @Override
-      public Instruction deserialize(JsonElement src, Type type,
-          JsonDeserializationContext context) {
-        JsonObject jo = src.getAsJsonObject();
-        Operation operation = Operation.valueOf(jo.getAsJsonPrimitive(KEY_OPERATION).getAsString());
-        AuthnAuthority authority = context.deserialize(jo.get(KEY_AUTHORITY), AuthnAuthority.class);
-        return Instruction.make(operation, authority,
-            context.deserialize(jo.get(KEY_OPERAND), operation.getOperandClass()));
-      }
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/authncontroller/ExportedState.java b/src/com/google/enterprise/secmgr/authncontroller/ExportedState.java
index aa8e748..203bbbe 100644
--- a/src/com/google/enterprise/secmgr/authncontroller/ExportedState.java
+++ b/src/com/google/enterprise/secmgr/authncontroller/ExportedState.java
@@ -18,14 +18,7 @@
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.enterprise.secmgr.common.GCookie;
-import com.google.enterprise.secmgr.config.AuthnMechBasic;
-import com.google.enterprise.secmgr.config.AuthnMechConnector;
-import com.google.enterprise.secmgr.config.AuthnMechLdap;
-import com.google.enterprise.secmgr.config.AuthnMechNtlm;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
 import com.google.enterprise.secmgr.config.ConfigSingleton;
-import com.google.enterprise.secmgr.http.ConnectorUtil;
 import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
 import com.google.enterprise.secmgr.json.TypeAdapters;
 import com.google.enterprise.secmgr.json.TypeProxy;
@@ -191,78 +184,18 @@
 
   @Nonnegative private final int version;
   @Nonnegative private final long timeStamp;
-  @Nonnull private final AuthnSessionState sessionState;
   @Nonnull private final Credentials pviCredentials;
   @Nonnull private final Credentials basicCredentials;
   @Nonnull private final ImmutableMap<String, Credentials> connectorCredentials;
-  @Nonnull private final ImmutableSet<GCookie> cookies;
 
   private ExportedState(@Nonnegative int version, @Nonnegative long timeStamp,
-      AuthnSessionState sessionState, Credentials pviCredentials, Credentials basicCredentials,
-      ImmutableMap<String, Credentials> connectorCredentials, ImmutableSet<GCookie> cookies) {
+      Credentials pviCredentials, Credentials basicCredentials,
+      ImmutableMap<String, Credentials> connectorCredentials) {
     this.version = version;
     this.timeStamp = timeStamp;
-    this.sessionState = sessionState;
     this.pviCredentials = pviCredentials;
     this.basicCredentials = basicCredentials;
     this.connectorCredentials = connectorCredentials;
-    this.cookies = cookies;
-  }
-
-  /**
-   * Makes an exported-state object from a given session snapshot.
-   *
-   * @param snapshot A snapshot to derive the exported state from.
-   * @return A corresponding exported-state object.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static ExportedState make(SessionSnapshot snapshot) {
-    long timeStamp = snapshot.getTimeStamp();
-    Credentials pviCredentials
-        = credentialsForView(snapshot.getPrimaryVerifiedView(), Credentials.EMPTY);
-    Credentials basicCredentials = credentialsForView(getBasicView(snapshot), pviCredentials);
-    ImmutableMap.Builder<String, Credentials> connectorCredentialsBuilder = ImmutableMap.builder();
-    for (String instanceName : ConnectorUtil.getUrlMap().keySet()) {
-      connectorCredentialsBuilder.put(instanceName,
-          credentialsForView(findConnectorView(instanceName, snapshot), pviCredentials));
-    }
-    ImmutableMap<String, Credentials> connectorCredentials = connectorCredentialsBuilder.build();
-    ImmutableSet<GCookie> cookies = ImmutableSet.copyOf(snapshot.getView().getAuthorityCookies());
-    return new ExportedState(CURRENT_VERSION, timeStamp, snapshot.getState(), pviCredentials,
-        basicCredentials, connectorCredentials, cookies);
-  }
-
-  private static Credentials credentialsForView(SessionView view, Credentials fallback) {
-    if (view == null) {
-      return fallback;
-    }
-    if (view.hasVerifiedPrincipalAndPassword()) {
-      return Credentials.make(view.getUsername(), view.getDomain(), view.getPassword(),
-          view.getGroups());
-    }
-    return Credentials.EMPTY;
-  }
-
-  private static SessionView getBasicView(SessionSnapshot snapshot) {
-    for (AuthnMechanism mechanism : snapshot.getConfig().getMechanisms()) {
-      if (mechanism instanceof AuthnMechBasic
-          || mechanism instanceof AuthnMechLdap
-          || mechanism instanceof AuthnMechNtlm) {
-        return snapshot.getView(mechanism);
-      }
-    }
-    return null;
-  }
-
-  private static SessionView findConnectorView(String instanceName, SessionSnapshot snapshot) {
-    for (AuthnMechanism mechanism : snapshot.getConfig().getMechanisms()) {
-      if (mechanism instanceof AuthnMechConnector
-          && instanceName.equals(((AuthnMechConnector) mechanism).getConnectorName())) {
-        return snapshot.getView(mechanism);
-      }
-    }
-    return null;
   }
 
   /**
@@ -275,16 +208,6 @@
   }
 
   /**
-   * Gets the security manager's session state, consisting of all cookies,
-   * credentials, and verifications generated during authentication.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState getSessionState() {
-    return sessionState;
-  }
-
-  /**
    * Gets the credentials for the Primary Verified Identity (PVI).
    */
   @CheckReturnValue
@@ -314,15 +237,6 @@
   }
 
   /**
-   * Gets all the cookies collected by the security manager.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public ImmutableSet<GCookie> getCookies() {
-    return cookies;
-  }
-
-  /**
    * Gets a JSON string representation for this object.
    */
   @CheckReturnValue
@@ -340,15 +254,13 @@
     return ConfigSingleton.getGson().fromJson(jsonString, ExportedState.class);
   }
 
-  static void registerTypeAdapters(GsonBuilder builder) {
+  public static void registerTypeAdapters(GsonBuilder builder) {
     builder.registerTypeAdapter(Credentials.class,
         ProxyTypeAdapter.make(Credentials.class, Credentials.LocalProxy.class));
     builder.registerTypeAdapter(ExportedState.class,
         ProxyTypeAdapter.make(ExportedState.class, LocalProxy.class));
     builder.registerTypeAdapter(new TypeToken<ImmutableSet<String>>() {}.getType(),
         TypeAdapters.immutableSet());
-    builder.registerTypeAdapter(new TypeToken<ImmutableSet<GCookie>>() {}.getType(),
-        TypeAdapters.immutableSet());
     builder.registerTypeAdapter(new TypeToken<ImmutableMap<String, Credentials>>() {}.getType(),
         TypeAdapters.immutableMap());
   }
@@ -356,11 +268,9 @@
   private static final class LocalProxy implements TypeProxy<ExportedState> {
     int version;
     long timeStamp;
-    AuthnSessionState sessionState;
     Credentials pviCredentials;
     Credentials basicCredentials;
     ImmutableMap<String, Credentials> connectorCredentials;
-    ImmutableSet<GCookie> cookies;
 
     @SuppressWarnings("unused")
     LocalProxy() {
@@ -370,20 +280,17 @@
     LocalProxy(ExportedState state) {
       version = state.version;
       timeStamp = state.timeStamp;
-      sessionState = state.getSessionState();
       pviCredentials = state.getPviCredentials();
       basicCredentials = state.getBasicCredentials();
       connectorCredentials = state.getConnectorCredentials();
-      cookies = state.getCookies();
     }
 
     @Override
     public ExportedState build() {
       Preconditions.checkArgument(version >= MIN_VERSION && version <= MAX_VERSION);
       Preconditions.checkArgument(timeStamp >= 0);
-      Preconditions.checkArgument(sessionState != null);
-      return new ExportedState(version, timeStamp, sessionState, pviCredentials, basicCredentials,
-          ImmutableMap.copyOf(connectorCredentials), ImmutableSet.copyOf(cookies));
+      return new ExportedState(version, timeStamp, pviCredentials, basicCredentials,
+          ImmutableMap.copyOf(connectorCredentials));
     }
   }
 }
diff --git a/src/com/google/enterprise/secmgr/authncontroller/SessionSnapshot.java b/src/com/google/enterprise/secmgr/authncontroller/SessionSnapshot.java
deleted file mode 100644
index c18e187..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/SessionSnapshot.java
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Maps;
-import com.google.enterprise.secmgr.common.GCookie;
-import com.google.enterprise.secmgr.common.SecurityManagerUtil;
-import com.google.enterprise.secmgr.common.SessionUtil;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
-import com.google.enterprise.secmgr.config.CredentialGroup;
-import com.google.enterprise.secmgr.config.SecurityManagerConfig;
-import com.google.enterprise.secmgr.identity.Verification;
-
-import org.joda.time.DateTimeUtils;
-import org.joda.time.format.ISODateTimeFormat;
-
-import java.net.URL;
-import java.util.Map;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * An immutable snapshot of the session's state.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class SessionSnapshot {
-  @Nonnull private final String sessionId;
-  @Nonnull private final SecurityManagerConfig config;
-  @Nullable private final URL authnEntryUrl;
-  @Nonnull private final ImmutableCollection<GCookie> userAgentCookies;
-  @Nonnull private final AuthnSessionState state;
-  @Nonnegative private final long timeStamp;
-  @Nonnull private final SessionView unspecializedView;
-  @GuardedBy("itself")
-  @Nonnull private final Map<AuthnMechanism, SessionView> savedMechanismViews;
-  @GuardedBy("itself")
-  @Nonnull private final Map<CredentialGroup, SessionView> savedCredentialGroupViews;
-
-  private SessionSnapshot(String sessionId, SecurityManagerConfig config,
-      @Nullable URL authnEntryUrl, ImmutableCollection<GCookie> userAgentCookies,
-      AuthnSessionState state, @Nonnegative long timeStamp) {
-    this.sessionId = sessionId;
-    this.config = config;
-    this.authnEntryUrl = authnEntryUrl;
-    this.userAgentCookies = userAgentCookies;
-    this.state = state;
-    this.timeStamp = timeStamp;
-    unspecializedView = SessionView.create(this);
-    savedMechanismViews = Maps.newHashMap();
-    savedCredentialGroupViews = Maps.newHashMap();
-  }
-
-  static SessionSnapshot make(String sessionId, SecurityManagerConfig config,
-      @Nullable URL authnEntryUrl, ImmutableCollection<GCookie> userAgentCookies,
-      AuthnSessionState state) {
-    return new SessionSnapshot(sessionId, config, authnEntryUrl, userAgentCookies,
-        state, DateTimeUtils.currentTimeMillis());
-  }
-
-  @VisibleForTesting
-  public static SessionSnapshot make(SecurityManagerConfig config, AuthnSessionState state) {
-    return make(SessionUtil.generateId(), config, null, ImmutableList.<GCookie>of(), state);
-  }
-
-  SessionSnapshot withNewUserAgentCookies(ImmutableCollection<GCookie> userAgentCookies) {
-    return new SessionSnapshot(sessionId, config, authnEntryUrl, userAgentCookies,
-        state, timeStamp);
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  public String getSessionId() {
-    return sessionId;
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  public SecurityManagerConfig getConfig() {
-    return config;
-  }
-
-  @CheckReturnValue
-  @Nullable
-  URL getAuthnEntryUrl() {
-    return authnEntryUrl;
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  ImmutableCollection<GCookie> getUserAgentCookies() {
-    return userAgentCookies;
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  public AuthnSessionState getState() {
-    return state;
-  }
-
-  @CheckReturnValue
-  @Nonnegative
-  long getTimeStamp() {
-    return timeStamp;
-  }
-
-  /**
-   * Gets a view of this snapshot specialized for a given authentication
-   * mechanism.
-   *
-   * @param mechanism An authentication mechanism.
-   * @return A mechanism view of this snapshot.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public SessionView getView(AuthnMechanism mechanism) {
-    synchronized (savedMechanismViews) {
-      SessionView view = savedMechanismViews.get(mechanism);
-      if (view == null) {
-        view = SessionView.create(this, mechanism);
-        savedMechanismViews.put(mechanism, view);
-      }
-      return view;
-    }
-  }
-
-  /**
-   * Gets a view of this snapshot specialized for a given credential group.
-   *
-   * @param credentialGroup A credential group.
-   * @return A credential-group view of this snapshot.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public SessionView getView(CredentialGroup credentialGroup) {
-    synchronized (savedCredentialGroupViews) {
-      SessionView view = savedCredentialGroupViews.get(credentialGroup);
-      if (view == null) {
-        view = SessionView.create(this, credentialGroup);
-        savedCredentialGroupViews.put(credentialGroup, view);
-      }
-      return view;
-    }
-  }
-
-  /**
-   * Gets an unspecialized view of this snapshot.
-   *
-   * @return An unspecialized view of this snapshot.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public SessionView getView() {
-    return unspecializedView;
-  }
-
-  /**
-   * Gets the expiration time for this snapshot.
-   *
-   * @return The expiration time.
-   */
-  @CheckReturnValue
-  public long getExpirationTime() {
-    SessionView view = getView();
-    return view.isSatisfied()
-        ? Verification.minimumExpirationTime(view.getVerifications())
-        : timeStamp;
-  }
-
-  /**
-   * Get a "primary verified view".  This is a view containing a principal
-   * that's been verified, with preference given to the default credential
-   * group's view, if possible.
-   *
-   * <p>The primary verified view is intended for use by the GSA, and this
-   * method is only called when generating output for the GSA.  It should
-   * <b>never</b> be used for any other purpose.
-   *
-   * @return The primary verified view, or null if there isn't one.
-   */
-  public SessionView getPrimaryVerifiedView() {
-    SessionView winner = null;
-    for (CredentialGroup credentialGroup : getConfig().getCredentialGroups()) {
-      SessionView view = getView(credentialGroup);
-      if (view.hasVerifiedPrincipal()) {
-        if (credentialGroup.isDefault()) {
-          return view;
-        }
-        if (winner == null) {
-          winner = view;
-        }
-      }
-    }
-    return winner;
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  public String logMessage(String format, Object... args) {
-    return SecurityManagerUtil.sessionLogMessage(sessionId, String.format(format, args));
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append("{SessionSnapshot taken at ");
-    builder.append(ISODateTimeFormat.dateTime().print(timeStamp));
-    builder.append(" of session ");
-    builder.append(sessionId);
-    builder.append("}");
-    return builder.toString();
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/authncontroller/SessionView.java b/src/com/google/enterprise/secmgr/authncontroller/SessionView.java
deleted file mode 100644
index 1fd6157..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/SessionView.java
+++ /dev/null
@@ -1,643 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableCollection;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.enterprise.secmgr.common.GCookie;
-import com.google.enterprise.secmgr.config.AuthnAuthority;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
-import com.google.enterprise.secmgr.config.CredentialGroup;
-import com.google.enterprise.secmgr.identity.AuthnPrincipal;
-import com.google.enterprise.secmgr.identity.CredPassword;
-import com.google.enterprise.secmgr.identity.Credential;
-import com.google.enterprise.secmgr.identity.GroupMemberships;
-import com.google.enterprise.secmgr.identity.Verification;
-import com.google.enterprise.secmgr.identity.VerificationStatus;
-
-import java.net.URL;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A view of a session snapshot that may be specialized or unspecialized.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public abstract class SessionView {
-
-  @Nonnull protected final SessionSnapshot snapshot;
-  @GuardedBy("this") @Nonnull protected AuthnSessionState.Summary summary;
-
-  protected SessionView(SessionSnapshot snapshot) {
-    Preconditions.checkNotNull(snapshot);
-    this.snapshot = snapshot;
-    summary = null;
-  }
-
-  /**
-   * Creates a session view specialized for a given authentication mechanism.
-   *
-   * @param snapshot The session snapshot the view is a specialization of.
-   * @param mechanism The authentication mechanism to specialize for.
-   * @return A view of the snapshot specialized for the mechanism.
-   */
-  @CheckReturnValue
-  @Nonnull
-  static SessionView create(SessionSnapshot snapshot, AuthnMechanism mechanism) {
-    return new SessionViewForMechanism(snapshot, mechanism);
-  }
-
-  /**
-   * Creates a session view specialized for a given credential group.
-   *
-   * @param snapshot The session snapshot the view is a specialization of.
-   * @param credentialGroup The credential group to specialize for.
-   * @return A view of the snapshot specialized for the credential group.
-   */
-  @CheckReturnValue
-  @Nonnull
-  static SessionView create(SessionSnapshot snapshot, CredentialGroup credentialGroup) {
-    return new SessionViewForCredentialGroup(snapshot, credentialGroup);
-  }
-
-  /**
-   * Creates an unspecialized session view.
-   *
-   * @param snapshot The session snapshot the view is a specialization of.
-   * @return An unspecialized view of the snapshot.
-   */
-  @CheckReturnValue
-  @Nonnull
-  static SessionView create(SessionSnapshot snapshot) {
-    return new SessionViewUnspecialized(snapshot);
-  }
-
-  /**
-   * Gets a new view identical to this one except that it contains the given
-   * user-agent cookies.  Used to update a view after returning from a
-   * credentials gatherer.
-   *
-   * @param userAgentCookies The new user-agent cookies.
-   * @return A new view as specified.
-   */
-  @CheckReturnValue
-  @Nonnull
-  SessionView withNewUserAgentCookies(ImmutableCollection<GCookie> userAgentCookies) {
-    return withNewSnapshot(snapshot.withNewUserAgentCookies(userAgentCookies));
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  protected abstract SessionView withNewSnapshot(SessionSnapshot snapshot);
-
-  /**
-   * Is this a mechanism view?
-   *
-   * @return True only if this view is specialized for an authentication mechanism.
-   */
-  @CheckReturnValue
-  public boolean isSpecializedForMechanism() {
-    return false;
-  }
-
-  /**
-   * Is this a credential-group view?
-   *
-   * @return True only if this view is specialized for a credential group.
-   */
-  @CheckReturnValue
-  public boolean isSpecializedForCredentialGroup() {
-    return false;
-  }
-
-  /**
-   * Is this an unspecialized view?
-   *
-   * @return True only if this is an unspecialized view.
-   */
-  @CheckReturnValue
-  public boolean isUnspecialized() {
-    return false;
-  }
-
-  /**
-   * Gets a summary of the view's session state.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public synchronized AuthnSessionState.Summary getSummary() {
-    if (summary == null) {
-      summary = snapshot.getState().computeSummary(snapshot.getConfig().getCredentialGroups());
-    }
-    return summary;
-  }
-
-  /**
-   * Gets the session ID string.
-   *
-   * @return The session ID string.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String getSessionId() {
-    return snapshot.getSessionId();
-  }
-
-  /**
-   * Gets the URL that initiated the current authentication request.
-   *
-   * @return The authentication request URL, or null if we're not processing an
-   *     authentication request.
-   */
-  @CheckReturnValue
-  @Nullable
-  public URL getAuthnEntryUrl() {
-    return snapshot.getAuthnEntryUrl();
-  }
-
-  /**
-   * Gets the URL that initiated the current authentication request.
-   *
-   * @return The authentication request URL as a string, or null if we're not
-   *     processing an authentication request.
-   */
-  @CheckReturnValue
-  @Nullable
-  public String getAuthnEntryUrlString() {
-    return getAuthnEntryUrl().toString();
-  }
-
-  /**
-   * Gets the time at which this view's snapshot was taken.
-   *
-   * @return The snapshot time in milliseconds since the epoch.
-   */
-  @CheckReturnValue
-  @Nonnegative
-  public long getTimeStamp() {
-    return snapshot.getTimeStamp();
-  }
-
-  /**
-   * Gets this view's authority, if it is a specialized view.
-   *
-   * @return The authority.
-   * @throws UnsupportedOperationException if this is not a specialized view.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public abstract AuthnAuthority getAuthority();
-
-  /**
-   * Gets this view's credential group, if this is a specialized view.
-   *
-   * @return The credential group.
-   * @throws UnsupportedOperationException if this is not a specialized view.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public abstract CredentialGroup getCredentialGroup();
-
-  /**
-   * Gets this view's mechanism, if this is a mechanism view.
-   *
-   * @return The mechanism associated with this view.
-   * @throws UnsupportedOperationException if this is not a mechanism view.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public abstract AuthnMechanism getMechanism();
-
-  /**
-   * Is this view's credential group required to have a principal?
-   *
-   * @return True if a principal is required.
-   * @throws UnsupportedOperationException if this is not a specialized view.
-   */
-  @CheckReturnValue
-  public boolean getRequiresPrincipal() {
-    return getCredentialGroup().getRequiresUsername();
-  }
-
-  /**
-   * Gets the configured expiration time.
-   *
-   * @return The expiration time.
-   * @throws UnsupportedOperationException if this is not a mechanism view.
-   */
-  @CheckReturnValue
-  public long getConfiguredExpirationTime() {
-    long trustDuration = getMechanism().getTrustDuration();
-    return (trustDuration > 0)
-        ? snapshot.getTimeStamp() + trustDuration
-        : Verification.EXPIRES_AFTER_REQUEST;
-  }
-
-  protected abstract Predicate<AuthnAuthority> getCookieFilter();
-  protected abstract Predicate<AuthnAuthority> getCredentialFilter();
-
-  /**
-   * Is this view satisfied?
-   */
-  @CheckReturnValue
-  public abstract boolean isSatisfied();
-
-  // **************** Cookies ****************
-
-  /**
-   * Gets the cookies that were received from the user agent in the most recent
-   * HTTP request.
-   *
-   * @return The cookies.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Iterable<GCookie> getUserAgentCookies() {
-    return snapshot.getUserAgentCookies();
-  }
-
-  /**
-   * Gets a user-agent cookie by name.  Note that there can be multiple such
-   * cookies; in that case one is chosen arbitrarily.
-   *
-   * @param name The name of the cookie to get.
-   * @return A cookie with that name, or {@code null} if none.
-   */
-  @CheckReturnValue
-  @Nullable
-  public GCookie getUserAgentCookie(String name) {
-    Preconditions.checkNotNull(name);
-    for (GCookie cookie : getUserAgentCookies()) {
-      if (name.equals(cookie.getName())) {
-        return cookie;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Gets the cookies that have been received from this view's authorities.
-   *
-   * @return An immutable set of the authority cookies.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public ImmutableSet<GCookie> getAuthorityCookies() {
-    return getSummary().getCookies(getCookieFilter(), getTimeStamp());
-  }
-
-  // **************** Credentials ****************
-
-  /**
-   * Gets the credentials that have been gathered for this view.
-   *
-   * @return An immutable set of the credentials.
-   */
-  public ImmutableSet<Credential> getCredentials() {
-    return getSummary().getCredentials(getCredentialFilter());
-  }
-
-  /**
-   * Gets this view's principal.
-   *
-   * @return The principal, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public AuthnPrincipal getPrincipal() {
-    return getUniqueCredential(AuthnPrincipal.class);
-  }
-
-  /**
-   * Gets this view's password credential.
-   *
-   * @return The password credential, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public CredPassword getPasswordCredential() {
-    return getUniqueCredential(CredPassword.class);
-  }
-
-  /**
-   * Gets this view's group-memberships credential.
-   *
-   * @return The group-memberships credential, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public GroupMemberships getGroupMemberships() {
-    return getUniqueCredential(GroupMemberships.class);
-  }
-
-  private <T extends Credential> T getUniqueCredential(Class<T> clazz) {
-    Credential uniqueCredential = null;
-    for (Credential credential : getCredentials()) {
-      if (clazz.isInstance(credential)) {
-        if (uniqueCredential == null) {
-          uniqueCredential = credential;
-        } else if (!uniqueCredential.equals(credential)) {
-          return null;
-        }
-      }
-    }
-    return clazz.cast(uniqueCredential);
-  }
-
-  /**
-   * Does this view have a principal and a password?
-   *
-   * @return True if the view has exactly one principal and one password.
-   */
-  @CheckReturnValue
-  public boolean hasPrincipalAndPassword() {
-    return hasPrincipalAndPassword(getPrincipal(), getPasswordCredential());
-  }
-
-  private boolean hasPrincipalAndPassword(AuthnPrincipal principal, CredPassword password) {
-    return principal != null
-        && !principal.getName().isEmpty()
-        && password != null
-        && !password.getText().isEmpty();
-  }
-
-  /**
-   * Gets this view's principal and password.
-   *
-   * @return An immutable collection containing those credentials.
-   * @throws IllegalStateException unless both are available.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public ImmutableCollection<Credential> getPrincipalAndPassword() {
-    AuthnPrincipal principal = getPrincipal();
-    CredPassword password = getPasswordCredential();
-    Preconditions.checkState(hasPrincipalAndPassword(principal, password));
-    return ImmutableList.<Credential>of(principal, password);
-  }
-
-  /**
-   * Gets this view's username.
-   *
-   * @return The username, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public String getUsername() {
-    AuthnPrincipal principal = getPrincipal();
-    return (principal != null) ? principal.getName() : null;
-  }
-
-  /**
-   * Gets this view's domain.
-   *
-   * @return The domain, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public String getDomain() {
-    AuthnPrincipal principal = getPrincipal();
-    return (principal != null) ? principal.getActiveDirectoryDomain() : null;
-  }
-
-  /**
-   * Gets this view's password.
-   *
-   * @return The password, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public String getPassword() {
-    CredPassword password = getPasswordCredential();
-    return (password != null) ? password.getText() : null;
-  }
-
-  /**
-   * Gets this view's groups.
-   *
-   * @return The groups, as an immutable set.
-   */
-  @CheckReturnValue
-  @Nullable
-  public ImmutableSet<String> getGroups() {
-    GroupMemberships groups = getGroupMemberships();
-    return (groups != null) ? groups.getGroups() : ImmutableSet.<String>of();
-  }
-
-  // **************** Verifications ****************
-
-  /**
-   * Gets the verifications for this view.
-   *
-   * @return An immutable set of this view's verifications.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public ImmutableSet<Verification> getVerifications() {
-    return getSummary().getVerifications(getCredentialFilter(), getTimeStamp());
-  }
-
-  /**
-   * Does this view have a verified principal?
-   *
-   * @return True if this view has at least one verification containing a
-   *     principal, and if no other verification contains a different principal.
-   */
-  @CheckReturnValue
-  public boolean hasVerifiedPrincipal() {
-    return null != getUniqueVerifiedCredential(AuthnPrincipal.class);
-  }
-
-  /**
-   * Does this view have a verified password?
-   *
-   * @return True if this view has at least one verification containing a
-   *     password, and if no other verification contains a different password.
-   */
-  @CheckReturnValue
-  protected boolean hasVerifiedPassword() {
-    return null != getUniqueVerifiedCredential(AuthnPrincipal.class);
-  }
-
-  /**
-   * Does this view have a jointly verified principal and password?
-   *
-   * @return True if this view has at least one verification containing both a
-   *     principal and password, and if no other verification contains a
-   *     different principal or password.
-   */
-  @CheckReturnValue
-  public boolean hasVerifiedPrincipalAndPassword() {
-    AuthnPrincipal principal = getUniqueVerifiedCredential(AuthnPrincipal.class);
-    CredPassword password = getUniqueVerifiedCredential(CredPassword.class);
-    return principal != null
-        && password != null
-        && areJointlyVerified(principal, password);
-  }
-
-  /**
-   * Gets a verified principal.
-   *
-   * @return The verified principal.  Returns {@code null} if
-   *     {@code hasVerifiedPrincipal()} is false.
-   */
-  @CheckReturnValue
-  @Nullable
-  public AuthnPrincipal getVerifiedPrincipal() {
-    return getUniqueVerifiedCredential(AuthnPrincipal.class);
-  }
-
-  /**
-   * Gets the verified groups for this view.
-   *
-   * @return The verified groups, may be empty.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public ImmutableSet<String> getVerifiedGroups() {
-    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
-    for (GroupMemberships credential : getVerifiedCredentials(GroupMemberships.class)) {
-      builder.addAll(credential.getGroups());
-    }
-    return builder.build();
-  }
-
-  /**
-   * Gets the expiration time of a credential.
-   *
-   * @param credential A credential to get the expiration time for.
-   * @return The credential's expiration time, or {@code 0} if the credential
-   *     isn't verified.
-   */
-  @CheckReturnValue
-  public long getCredentialExpirationTime(Credential credential) {
-    Preconditions.checkNotNull(credential);
-    return Verification.maximumExpirationTime(getJointVerifications(credential));
-  }
-
-  private <T extends Credential> T getUniqueVerifiedCredential(Class<T> clazz) {
-    Credential uniqueCredential = null;
-    for (Verification verification : getVerifications()) {
-      if (verification.isVerified()) {
-        for (Credential credential : verification.getCredentials()) {
-          if (clazz.isInstance(credential)) {
-            if (uniqueCredential == null) {
-              uniqueCredential = credential;
-            } else if (!uniqueCredential.equals(credential)) {
-              return null;
-            }
-          }
-        }
-      }
-    }
-    return clazz.cast(uniqueCredential);
-  }
-
-  private <T extends Credential> Iterable<T> getVerifiedCredentials(Class<T> clazz) {
-    ImmutableList.Builder<T> builder = ImmutableList.builder();
-    for (Verification verification : getVerifications()) {
-      if (verification.isVerified()) {
-        for (Credential credential : verification.getCredentials()) {
-          if (clazz.isInstance(credential)) {
-            builder.add(clazz.cast(credential));
-          }
-        }
-      }
-    }
-    return builder.build();
-  }
-
-  private boolean areJointlyVerified(Credential... credentials) {
-    return Iterables.any(getVerifications(),
-        Predicates.and(
-            Verification.isVerifiedPredicate(),
-            Verification.getContainsAllCredentialsPredicate(credentials)));
-  }
-
-  private Iterable<Verification> getJointVerifications(Credential... credentials) {
-    return Iterables.filter(getVerifications(),
-        Predicates.and(
-            Verification.isVerifiedPredicate(),
-            Verification.getContainsAllCredentialsPredicate(credentials)));
-  }
-
-  /**
-   * Gets this view's verification status.
-   *
-   * @return The verification status.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public VerificationStatus getVerificationStatus() {
-    return Verification.getStatus(getVerifications());
-  }
-
-  /**
-   * Does this view have no refutations and at least one verification?
-   *
-   * @return True if this view is verified.
-   */
-  @CheckReturnValue
-  public boolean isVerified() {
-    return getVerificationStatus() == VerificationStatus.VERIFIED;
-  }
-
-  /**
-   * Does this view have at least one refutation?
-   *
-   * @return True if this view is refuted.
-   */
-  @CheckReturnValue
-  public boolean isRefuted() {
-    return getVerificationStatus() == VerificationStatus.REFUTED;
-  }
-
-  /**
-   * Does this view have no refutations and no verifications?
-   *
-   * @return True if this view is indeterminate.
-   */
-  @CheckReturnValue
-  public boolean isIndeterminate() {
-    return getVerificationStatus() == VerificationStatus.INDETERMINATE;
-  }
-
-  // **************** Logging ****************
-
-  /**
-   * Annotates a log message with this view's session ID.
-   *
-   * @param format The format string to pass to {@link String#format}.
-   * @param args The arguments to pass to {@link String#format}.
-   * @return The annotated log message.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String logMessage(String format, Object... args) {
-    return snapshot.logMessage(format, args);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/authncontroller/SessionViewForCredentialGroup.java b/src/com/google/enterprise/secmgr/authncontroller/SessionViewForCredentialGroup.java
deleted file mode 100644
index bf427c4..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/SessionViewForCredentialGroup.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.enterprise.secmgr.config.AuthnAuthority;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
-import com.google.enterprise.secmgr.config.CredentialGroup;
-import com.google.enterprise.secmgr.identity.AuthnPrincipal;
-import com.google.enterprise.secmgr.identity.CredPassword;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A view of a session snapshot that's specialized for a credential group.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-final class SessionViewForCredentialGroup extends SessionView {
-
-  @Nonnull private final CredentialGroup credentialGroup;
-
-  SessionViewForCredentialGroup(SessionSnapshot snapshot, CredentialGroup credentialGroup) {
-    super(snapshot);
-    Preconditions.checkNotNull(credentialGroup);
-    Preconditions.checkState(
-        snapshot.getConfig().getCredentialGroups().contains(credentialGroup));
-    this.credentialGroup = credentialGroup;
-  }
-
-  @Override
-  protected SessionView withNewSnapshot(SessionSnapshot snapshot) {
-    return snapshot.getView(credentialGroup);
-  }
-
-  @Override
-  public boolean isSpecializedForCredentialGroup() {
-    return true;
-  }
-
-  @Override
-  public AuthnAuthority getAuthority() {
-    return credentialGroup.getAuthority();
-  }
-
-  @Override
-  public AuthnMechanism getMechanism() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public CredentialGroup getCredentialGroup() {
-    return credentialGroup;
-  }
-
-  @Override
-  protected Predicate<AuthnAuthority> getCookieFilter() {
-    return snapshot.getConfig().getAuthorityPredicate(credentialGroup);
-  }
-
-  @Override
-  protected Predicate<AuthnAuthority> getCredentialFilter() {
-    return snapshot.getConfig().getAuthorityPredicate(credentialGroup);
-  }
-
-  @Override
-  public boolean isSatisfied() {
-    if (credentialGroup.getMechanisms().isEmpty()) {
-      // An empty group is never satisfied.
-      logMessage("Credential group %s not satisfied because it is empty.",
-          credentialGroup.getName());
-      return false;
-    }
-
-    if (isRefuted()) {
-      logMessage("Credential group %s not satisfied because it is refuted.",
-          credentialGroup.getName());
-      return false;
-    }
-
-    // If principal is required, it must be present and non-empty.
-    if (credentialGroup.getRequiresUsername() && !hasVerifiedPrincipal()) {
-      logMessage("Credential group %s not satisfied because it requires a username.",
-          credentialGroup.getName());
-      return false;
-    }
-
-    // If password is required, it must be present and non-empty.
-    if (credentialGroup.getRequiresPassword() && !hasVerifiedPassword()) {
-      logMessage("Credential group %s not satisfied because it requires a password.",
-          credentialGroup.getName());
-      return false;
-    }
-
-    // If group is optional, empty principal and password are sufficient.
-    // Note that both the principal and the password must be present; otherwise
-    // that means we haven't yet gathered credentials, so we must not return
-    // satisfied.  When they are both empty, it means we gathered credentials
-    // and the user didn't fill them in.
-    if (credentialGroup.getIsOptional() && hasEmptyPrincipal() && hasEmptyPassword()) {
-      logMessage("Credential group %s satisfied because it's optional and was left blank.",
-          credentialGroup.getName());
-      return true;
-    }
-
-    // TODO(cph): This doesn't check the credentials -- so the username and/or
-    // password might not be verified.  Unfortunately, the program's current
-    // logic doesn't understand that credentials must be verified independently
-    // of the satisfaction of their identity group.
-    return isVerified();
-  }
-
-  private boolean hasEmptyPrincipal() {
-    AuthnPrincipal principal = getPrincipal();
-    return principal != null && principal.getName().isEmpty();
-  }
-
-  private boolean hasEmptyPassword() {
-    CredPassword password = getPasswordCredential();
-    return password != null && password.getText().isEmpty();
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append("{SessionView of ");
-    builder.append(snapshot);
-    builder.append(" specialized for: ");
-    builder.append(credentialGroup);
-    builder.append("}");
-    return builder.toString();
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/authncontroller/SessionViewForMechanism.java b/src/com/google/enterprise/secmgr/authncontroller/SessionViewForMechanism.java
deleted file mode 100644
index a3acde1..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/SessionViewForMechanism.java
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.enterprise.secmgr.config.AuthnAuthority;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
-import com.google.enterprise.secmgr.config.CredentialGroup;
-import com.google.enterprise.secmgr.identity.Verification;
-import com.google.enterprise.secmgr.identity.VerificationStatus;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A view of a session snapshot that's specialized for an authority.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-final class SessionViewForMechanism extends SessionView {
-  @Nonnull private final AuthnMechanism mechanism;
-  @Nonnull private final CredentialGroup credentialGroup;
-
-  SessionViewForMechanism(SessionSnapshot snapshot, AuthnMechanism mechanism) {
-    super(snapshot);
-    Preconditions.checkNotNull(mechanism);
-    this.mechanism = mechanism;
-    credentialGroup = snapshot.getConfig().getCredentialGroup(mechanism);
-  }
-
-  @Override
-  protected SessionView withNewSnapshot(SessionSnapshot snapshot) {
-    return snapshot.getView(mechanism);
-  }
-
-  @Override
-  public boolean isSpecializedForMechanism() {
-    return true;
-  }
-
-  @Override
-  public AuthnAuthority getAuthority() {
-    return mechanism.getAuthority();
-  }
-
-  @Override
-  public CredentialGroup getCredentialGroup() {
-    return credentialGroup;
-  }
-
-  @Override
-  public AuthnMechanism getMechanism() {
-    return mechanism;
-  }
-
-  @Override
-  protected Predicate<AuthnAuthority> getCookieFilter() {
-    return Predicates.equalTo(getAuthority());
-  }
-
-  @Override
-  protected Predicate<AuthnAuthority> getCredentialFilter() {
-    return snapshot.getConfig().getAuthorityPredicate(credentialGroup);
-  }
-
-  @Override
-  public VerificationStatus getVerificationStatus() {
-    return Verification.getStatus(
-        getSummary().getVerifications(Predicates.equalTo(getAuthority()), getTimeStamp()));
-  }
-
-  @Override
-  public boolean isSatisfied() {
-    return isVerified();
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append("{SessionView of ");
-    builder.append(snapshot);
-    builder.append(" specialized for: ");
-    builder.append(mechanism);
-    builder.append("}");
-    return builder.toString();
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/authncontroller/SessionViewUnspecialized.java b/src/com/google/enterprise/secmgr/authncontroller/SessionViewUnspecialized.java
deleted file mode 100644
index 063ab9f..0000000
--- a/src/com/google/enterprise/secmgr/authncontroller/SessionViewUnspecialized.java
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.authncontroller;
-
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.Lists;
-import com.google.enterprise.secmgr.config.AuthnAuthority;
-import com.google.enterprise.secmgr.config.AuthnMechanism;
-import com.google.enterprise.secmgr.config.CredentialGroup;
-
-import java.util.List;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A view of a session snapshot that's not specialized.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-final class SessionViewUnspecialized extends SessionView {
-
-  SessionViewUnspecialized(final SessionSnapshot snapshot) {
-    super(snapshot);
-  }
-
-  @Override
-  protected SessionView withNewSnapshot(SessionSnapshot snapshot) {
-    return snapshot.getView();
-  }
-
-  @Override
-  public boolean isUnspecialized() {
-    return true;
-  }
-
-  @Override
-  public AuthnAuthority getAuthority() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public CredentialGroup getCredentialGroup() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public AuthnMechanism getMechanism() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  protected Predicate<AuthnAuthority> getCookieFilter() {
-    return Predicates.alwaysTrue();
-  }
-
-  @Override
-  protected Predicate<AuthnAuthority> getCredentialFilter() {
-    return Predicates.alwaysTrue();
-  }
-
-  @Override
-  public boolean isSatisfied() {
-    List<CredentialGroup> nonEmpty = Lists.newArrayList();
-    for (CredentialGroup credentialGroup : snapshot.getConfig().getCredentialGroups()) {
-      if (!credentialGroup.getMechanisms().isEmpty()) {
-        nonEmpty.add(credentialGroup);
-      }
-    }
-    if (nonEmpty.isEmpty()) {
-      logMessage("No non-empty credential groups, so nothing to be satisfied.");
-      return false;
-    }
-    for (CredentialGroup credentialGroup : nonEmpty) {
-      if (!snapshot.getView(credentialGroup).isSatisfied()) {
-        logMessage("Credential group %s reports not satisfied, so session is not satisfied.",
-            credentialGroup.getName());
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append("{SessionView of ");
-    builder.append(snapshot);
-    builder.append("}");
-    return builder.toString();
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/Base64.java b/src/com/google/enterprise/secmgr/common/Base64.java
deleted file mode 100644
index fa88ccd..0000000
--- a/src/com/google/enterprise/secmgr/common/Base64.java
+++ /dev/null
@@ -1,477 +0,0 @@
-// Copyright 2002 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// This code was converted from code at http://iharder.sourceforge.net/base64/
-// Lots of extraneous features were removed.
-/* The original code said:
- * <p>
- * I am placing this code in the Public Domain. Do with it as you will.
- * This software comes with no guarantees or warranties but with
- * plenty of well-wishing instead!
- * Please visit
- * <a href="http://iharder.net/xmlizable">http://iharder.net/xmlizable</a>
- * periodically to check for updates or to contribute improvements.
- * </p>
- *
- * @author Robert Harder
- * @author rharder@usa.net
- * @version 1.3
- */
-
-package com.google.enterprise.secmgr.common;
-
-/**
- * Base64 converter class. This code is not a full-blown MIME encoder;
- * it simply converts binary data to base64 data and back.
- */
-public class Base64 {
-  /** Specify encoding (value is {@code true}). */
-  public static final boolean ENCODE = true;
-
-  /** Specify decoding (value is {@code false}). */
-  public static final boolean DECODE = false;
-
-  /** The equals sign (=) as a byte. */
-  private static final byte EQUALS_SIGN = (byte) '=';
-
-  /** The new line character (\n) as a byte. */
-  private static final byte NEW_LINE = (byte) '\n';
-
-  /** The 64 valid Base64 values. */
-  public static final byte[] ALPHABET =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
-      .getBytes();
-
-  /** The 64 valid web safe Base64 values. */
-  public static final byte[] WEBSAFE_ALPHABET =
-      "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
-      .getBytes();
-
-  /**
-   * Translates a Base64 value to either its 6-bit reconstruction value
-   * or a negative number indicating some other meaning.  This can decode
-   * content that was endoded with either the standard ALPHABET or the
-   * WEBSAFE_ALPHABET.
-   */
-  private static final byte[] DECODABET = {
-      -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal  0 -  8
-      -5, -5, // Whitespace: Tab and Linefeed
-      -9, -9, // Decimal 11 - 12
-      -5, // Whitespace: Carriage Return
-      -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 14 - 26
-      -9, -9, -9, -9, -9, // Decimal 27 - 31
-      -5, // Whitespace: Space
-      -9, -9, -9, -9, -9, -9, -9, -9, -9, -9, // Decimal 33 - 42
-      62, // Plus sign at decimal 43
-      -9, // Decimal 44
-      62, // Dash '-' sign at decimal 45 (from WebSafe encoding)
-      -9, // Decimal 46
-      63, // Slash at decimal 47
-      52, 53, 54, 55, 56, 57, 58, 59, 60, 61, // Numbers zero through nine
-      -9, -9, -9, // Decimal 58 - 60
-      -1, // Equals sign at decimal 61
-      -9, -9, -9, // Decimal 62 - 64
-      0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, // Letters 'A' through 'N'
-      14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, // Letters 'O' through 'Z'
-      -9, -9, -9, -9, // Decimal 91-94
-      63, // Underscore '_' at decimal 95 (from WebSafe encoding)
-      -9, // Decimal 96
-      26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, // Letters 'a' through 'm'
-      39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, // Letters 'n' through 'z'
-      -9, -9, -9, -9, -9 // Decimal 123 - 127
-  };
-
-  // Indicates white space in encoding.
-  private static final byte WHITE_SPACE_ENC = -5;
-
-  // Indicates equals sign in encoding.
-  private static final byte EQUALS_SIGN_ENC = -1;
-
-  private Base64() {
-    // Defeats instantiation.
-  }
-
-  /* ********  E N C O D I N G   M E T H O D S  ******** */
-
-  /**
-   * Encodes up to three bytes of the array <var>source</var>
-   * and writes the resulting four Base64 bytes to <var>destination</var>.
-   * The source and destination arrays can be manipulated
-   * anywhere along their length by specifying
-   * <var>srcOffset</var> and <var>destOffset</var>.
-   * This method does not check to make sure your arrays
-   * are large enough to accommodate <var>srcOffset</var> + 3 for
-   * the <var>source</var> array or <var>destOffset</var> + 4 for
-   * the <var>destination</var> array.
-   * The actual number of significant bytes in your array is
-   * given by <var>numSigBytes</var>.
-   *
-   * @param source the array to convert
-   * @param srcOffset the index where conversion begins
-   * @param numSigBytes the number of significant bytes in your array
-   * @param destination the array to hold the conversion
-   * @param destOffset the index where output will be put
-   * @param alphabet is the encoding alphabet
-   * @return the <var>destination</var> array
-   * @since 1.3
-   */
-  static byte[] encode3to4(byte[] source, int srcOffset,
-      int numSigBytes, byte[] destination, int destOffset, byte[] alphabet) {
-    //           1         2         3
-    // 01234567890123456789012345678901 Bit position
-    // --------000000001111111122222222 Array position from threeBytes
-    // --------|    ||    ||    ||    | Six bit groups to index alphabet
-    //          >>18  >>12  >> 6  >> 0  Right shift necessary
-    //                0x3f  0x3f  0x3f  Additional AND
-
-    // Create buffer with zero-padding if there are only one or two
-    // significant bytes passed in the array.
-    // We have to shift left 24 in order to flush out the 1's that appear
-    // when Java treats a value as negative that is cast from a byte to an int.
-    int inBuff =
-        (numSigBytes > 0 ? ((source[srcOffset] << 24) >>> 8) : 0)
-        | (numSigBytes > 1 ? ((source[srcOffset + 1] << 24) >>> 16) : 0)
-        | (numSigBytes > 2 ? ((source[srcOffset + 2] << 24) >>> 24) : 0);
-
-    switch (numSigBytes) {
-      case 3:
-        destination[destOffset] = alphabet[(inBuff >>> 18)];
-        destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
-        destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
-        destination[destOffset + 3] = alphabet[(inBuff) & 0x3f];
-        return destination;
-      case 2:
-        destination[destOffset] = alphabet[(inBuff >>> 18)];
-        destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
-        destination[destOffset + 2] = alphabet[(inBuff >>> 6) & 0x3f];
-        destination[destOffset + 3] = EQUALS_SIGN;
-        return destination;
-      case 1:
-        destination[destOffset] = alphabet[(inBuff >>> 18)];
-        destination[destOffset + 1] = alphabet[(inBuff >>> 12) & 0x3f];
-        destination[destOffset + 2] = EQUALS_SIGN;
-        destination[destOffset + 3] = EQUALS_SIGN;
-        return destination;
-      default:
-        return destination;
-    } // end switch
-  } // end encode3to4
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   * Equivalent to calling
-   * {@code encodeBytes(source, 0, source.length)}
-   *
-   * @param source The data to convert
-   * @since 1.4
-   */
-  public static String encode(byte[] source) {
-    return encode(source, 0, source.length, ALPHABET, true);
-  }
-
-  /**
-   * Encodes a byte array into web safe Base64 notation.
-   *
-   * @param source The data to convert
-   * @param doPadding is {@code true} to pad result with '=' chars
-   *        if it does not fall on 3 byte boundaries
-   */
-  public static String encodeWebSafe(byte[] source, boolean doPadding) {
-    return encode(source, 0, source.length, WEBSAFE_ALPHABET, doPadding);
-  }
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   *
-   * @param source The data to convert
-   * @param off Offset in array where conversion should begin
-   * @param len Length of data to convert
-   * @param alphabet is the encoding alphabet
-   * @param doPadding is {@code true} to pad result with '=' chars
-   *        if it does not fall on 3 byte boundaries
-   * @since 1.4
-   */
-  public static String encode(byte[] source, int off, int len, byte[] alphabet,
-      boolean doPadding) {
-    byte[] outBuff = encode(source, off, len, alphabet, Integer.MAX_VALUE);
-    int outLen = outBuff.length;
-
-    // If doPadding is false, set length to truncate '='
-    // padding characters
-    while (doPadding == false && outLen > 0) {
-      if (outBuff[outLen - 1] != '=') {
-        break;
-      }
-      outLen -= 1;
-    }
-
-    return new String(outBuff, 0, outLen);
-  }
-
-  /**
-   * Encodes a byte array into Base64 notation.
-   *
-   * @param source The data to convert
-   * @param off Offset in array where conversion should begin
-   * @param len Length of data to convert
-   * @param alphabet is the encoding alphabet
-   * @param maxLineLength maximum length of one line.
-   * @return the BASE64-encoded byte array
-   */
-  public static byte[] encode(byte[] source, int off, int len, byte[] alphabet,
-      int maxLineLength) {
-    int len43 = ((len + 2) / 3) * 4;
-    byte[] outBuff = new byte[len43 + (len43 / maxLineLength)];
-
-    encode(source, off, len, outBuff, 0, alphabet, maxLineLength);
-    return outBuff;
-  }
-
-  /**
-   * Encodes a byte array into Base64 notation into a destination byte array.
-   * Warning: No check is made to make sure the destination is big enough
-   * to hold the conversion.
-   * This was optimally constructed for use by Base64FilterInputStream.
-   *
-   * @param source The data to convert
-   * @param sourceOffset Offset in source array where conversion should begin
-   * @param sourceLength Length of data to convert
-   * @param dest The destination array for converted data
-   * @param destOffset Offset in destination array to write
-   * @param alphabet is the encoding alphabet
-   * @param maxLineLength maximum length of one line.
-   * @return the number of bytes written to destination.
-   */
-  static int encode(byte[] source, int sourceOffset, int sourceLength,
-      byte[] dest, int destOffset, byte[] alphabet, int maxLineLength) {
-    int s = 0;
-    int d = destOffset;
-    int len = sourceLength - 2;
-    int lineLength = 0;
-
-    for (; s < len; s += 3, d += 4) {
-      // The following block of code is the same as
-      // encode3to4( source, s + off, 3, dest, d, alphabet );
-      // but inlined for faster encoding (~20% improvement)
-      int inBuff =
-          ((source[s + sourceOffset] << 24) >>> 8)
-          | ((source[s + 1 + sourceOffset] << 24) >>> 16)
-          | ((source[s + 2 + sourceOffset] << 24) >>> 24);
-      dest[d] = alphabet[(inBuff >>> 18)];
-      dest[d + 1] = alphabet[(inBuff >>> 12) & 0x3f];
-      dest[d + 2] = alphabet[(inBuff >>> 6) & 0x3f];
-      dest[d + 3] = alphabet[(inBuff) & 0x3f];
-
-      if ((lineLength += 4) >= maxLineLength) {
-        dest[d + 4] = NEW_LINE;
-        d++;
-        lineLength = 0;
-      } // end if: end of line
-    } // end for: each piece of array
-
-    if (s < sourceLength) {
-      encode3to4(source, s + sourceOffset, sourceLength - s, dest, d, alphabet);
-      d += 4;
-      if ((lineLength += 4) >= maxLineLength) {
-        dest[d++] = NEW_LINE;
-      }
-    }
-
-    return d - destOffset;
-  }
-
-  /* ********  D E C O D I N G   M E T H O D S  ******** */
-
-  /**
-   * Decodes four bytes from array <var>source</var>
-   * and writes the resulting bytes (up to three of them)
-   * to <var>destination</var>.
-   * The source and destination arrays can be manipulated
-   * anywhere along their length by specifying
-   * <var>srcOffset</var> and <var>destOffset</var>.
-   * This method does not check to make sure your arrays
-   * are large enough to accommodate <var>srcOffset</var> + 4 for
-   * the <var>source</var> array or <var>destOffset</var> + 3 for
-   * the <var>destination</var> array.
-   * This method returns the actual number of bytes that
-   * were converted from the Base64 encoding.
-   *
-   *
-   * @param source the array to convert
-   * @param srcOffset the index where conversion begins
-   * @param destination the array to hold the conversion
-   * @param destOffset the index where output will be put
-   * @param decodabet the decodabet for decoding Base64 content
-   * @return the number of decoded bytes converted
-   * @since 1.3
-   */
-  private static int decode4to3(byte[] source, int srcOffset,
-      byte[] destination, int destOffset, byte[] decodabet) {
-    // Example: Dk==
-    if (source[srcOffset + 2] == EQUALS_SIGN) {
-      int outBuff =
-          ((decodabet[source[srcOffset]] << 24) >>> 6)
-          | ((decodabet[source[srcOffset + 1]] << 24) >>> 12);
-
-      destination[destOffset] = (byte) (outBuff >>> 16);
-      return 1;
-    } else if (source[srcOffset + 3] == EQUALS_SIGN) {
-      // Example: DkL=
-      int outBuff =
-          ((decodabet[source[srcOffset]] << 24) >>> 6)
-          | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
-          | ((decodabet[source[srcOffset + 2]] << 24) >>> 18);
-
-      destination[destOffset] = (byte) (outBuff >>> 16);
-      destination[destOffset + 1] = (byte) (outBuff >>> 8);
-      return 2;
-    } else {
-      // Example: DkLE
-      int outBuff =
-          ((decodabet[source[srcOffset]] << 24) >>> 6)
-          | ((decodabet[source[srcOffset + 1]] << 24) >>> 12)
-          | ((decodabet[source[srcOffset + 2]] << 24) >>> 18)
-          | ((decodabet[source[srcOffset + 3]] << 24) >>> 24);
-
-      destination[destOffset] = (byte) (outBuff >> 16);
-      destination[destOffset + 1] = (byte) (outBuff >> 8);
-      destination[destOffset + 2] = (byte) (outBuff);
-      return 3;
-    }
-  } // end decodeToBytes
-
-  /**
-   * Decodes data from Base64 notation.
-   * Understands either standard or web-safe encoding.
-   *
-   * @param s the string to decode (decoded in default encoding)
-   * @return the decoded data
-   * @since 1.4
-   */
-  public static byte[] decode(String s) throws Base64DecoderException {
-    byte[] bytes = s.getBytes();
-    return decode(bytes, 0, bytes.length, DECODABET);
-  }
-
-  /**
-   * Decodes Base64 content in byte array format and returns
-   * the decoded byte array.
-   * Understands either standard or web-safe encoding.
-   *
-   * @param source The Base64 encoded data
-   * @return decoded data
-   * @since 1.3
-   * @throws Base64DecoderException
-   */
-  public static byte[] decode(byte[] source) throws Base64DecoderException {
-    return decode(source, 0, source.length, DECODABET);
-  }
-
-  /**
-   * Decodes Base64 content in byte array format and returns
-   * the decoded byte array.
-   * Understands either standard or web-safe encoding.
-   *
-   * @param source The Base64 encoded data
-   * @param off    The offset of where to begin decoding
-   * @param len    The length of characters to decode
-   * @return decoded data
-   * @since 1.3
-   * @throws Base64DecoderException
-   */
-  public static byte[] decode(byte[] source, int off, int len)
-      throws Base64DecoderException {
-    return decode(source, off, len, DECODABET);
-  }
-
-  /**
-   * Decodes Base64 content using the supplied decodabet and returns
-   * the decoded byte array.
-   * Understands either standard or web-safe encoding.
-   *
-   * @param source    The Base64 encoded data
-   * @param off       The offset of where to begin decoding
-   * @param len       The length of characters to decode
-   * @param decodabet the decodabet for decoding Base64 content
-   * @return decoded data
-   */
-  public static byte[] decode(byte[] source, int off, int len, byte[] decodabet)
-      throws Base64DecoderException {
-    int len34 = len * 3 / 4;
-    byte[] outBuff = new byte[2 + len34]; // Upper limit on size of output
-    int outBuffPosn = 0;
-
-    byte[] b4 = new byte[4];
-    int b4Posn = 0;
-    int i = 0;
-    byte sbiCrop = 0;
-    byte sbiDecode = 0;
-    for (i = 0; i < len; i++) {
-      sbiCrop = (byte) (source[i + off] & 0x7f); // Only the low seven bits
-      sbiDecode = decodabet[sbiCrop];
-
-      if (sbiDecode >= WHITE_SPACE_ENC) { // White space Equals sign or better
-        if (sbiDecode >= EQUALS_SIGN_ENC) {
-          // An equals sign (for padding) must not occur at position 0 or 1
-          // and must be the last byte[s] in the encoded value.
-          if (sbiCrop == EQUALS_SIGN) {
-            int bytesLeft = len - i;
-            byte lastByte = (byte) (source[len - 1 + off] & 0x7f);
-            if (b4Posn == 0 || b4Posn == 1) {
-              throw new Base64DecoderException(
-                  "invalid padding byte '=' at byte offset " + i);
-            } else if ((b4Posn == 3 && bytesLeft > 2)
-                || (b4Posn == 4 && bytesLeft > 1)) {
-              throw new Base64DecoderException(
-                  "padding byte '=' falsely signals end of encoded value "
-                  + "at offset " + i);
-            } else if (lastByte != EQUALS_SIGN && lastByte != NEW_LINE) {
-              throw new Base64DecoderException(
-                  "encoded value has invalid trailing byte");
-            }
-            break;
-          }
-
-          b4[b4Posn++] = sbiCrop;
-          if (b4Posn == 4) {
-            outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
-            b4Posn = 0;
-          }
-        }
-      } else {
-        throw new Base64DecoderException("Bad Base64 input character at " + i
-            + ": " + source[i + off] + "(decimal)");
-      }
-    }
-
-    // Because web safe encoding allows non padding base64 encodes, we
-    // need to pad the rest of the b4 buffer with equal signs when
-    // b4Posn != 0.  There can be at most 2 equal signs at the end of
-    // four characters, so the b4 buffer must have two or three
-    // characters.  This also catches the case where the input is
-    // padded with EQUALS_SIGN.
-    if (b4Posn != 0) {
-      if (b4Posn == 1) {
-        throw new Base64DecoderException("single trailing character at offset "
-            + (len - 1));
-      }
-      b4[b4Posn++] = EQUALS_SIGN;
-      outBuffPosn += decode4to3(b4, 0, outBuff, outBuffPosn, decodabet);
-    }
-
-    byte[] out = new byte[outBuffPosn];
-    System.arraycopy(outBuff, 0, out, 0, outBuffPosn);
-    return out;
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/Base64DecoderException.java b/src/com/google/enterprise/secmgr/common/Base64DecoderException.java
deleted file mode 100644
index 39ac218..0000000
--- a/src/com/google/enterprise/secmgr/common/Base64DecoderException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2002 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//     http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-/**
- * Exception thrown when encountering an invalid Base64 input character.
- *
- * <p>This class may be used with the Google Web Toolkit (GWT).
- */
-public class Base64DecoderException extends Exception {
-  public Base64DecoderException() {
-    super();
-  }
-
-  public Base64DecoderException(String s) {
-    super(s);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/Chain.java b/src/com/google/enterprise/secmgr/common/Chain.java
deleted file mode 100644
index 064119e..0000000
--- a/src/com/google/enterprise/secmgr/common/Chain.java
+++ /dev/null
@@ -1,428 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * An immutable accumulator that adds elements to the end of a "chain" and can
- * later convert that to a {@link List}.
- *
- * @param <E> The type of the elements stored in this chain.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public abstract class Chain<E> implements Iterable<E> {
-
-  @Nonnull private static final Chain<?> EMPTY_CHAIN = new EmptyChain<Object>();
-
-  /**
-   * Gets a new chain with no elements.
-   */
-  @CheckReturnValue
-  @SuppressWarnings("unchecked")
-  @Nonnull
-  public static <F> Chain<F> empty() {
-    return (Chain<F>) EMPTY_CHAIN;
-  }
-
-  /**
-   * Gets a new chain with the given elements.
-   *
-   * @param elements The elements to make a chain from.
-   * @return A chain of those elements.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <F> Chain<F> copyOf(Iterable<F> elements) {
-    Chain<F> chain = empty();
-    for (F element : elements) {
-      chain = chain.add(element);
-    }
-    return chain;
-  }
-
-  /**
-   * Gets the number of elements in this chain.
-   *
-   * @return The number of elements.
-   */
-  @CheckReturnValue
-  @Nonnegative
-  public abstract int size();
-
-  /**
-   * Is this an empty chain?
-   *
-   * @return True if this chain has no elements.
-   */
-  @CheckReturnValue
-  public abstract boolean isEmpty();
-
-  /**
-   * Gets the last element in this chain.  That is, for any chain {@code C} and
-   * element {@code E}, {@code C.add(E).getLast() == E}.
-   *
-   * @return The last element in the chain.
-   * @throws UnsupportedOperationException if this is an empty chain.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public abstract E getLast();
-
-  /**
-   * Gets the rest of this chain.  That is, for any chain {@code C} and element
-   * {@code E}, {@code C.add(E).getRest() == C}.
-   *
-   * @return The rest of this chain.
-   * @throws UnsupportedOperationException if this is an empty chain.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public abstract Chain<E> getRest();
-
-  @Immutable
-  private static final class EmptyChain<F> extends Chain<F> {
-    @Override
-    public int size() {
-      return 0;
-    }
-
-    @Override
-    public boolean isEmpty() {
-      return true;
-    }
-
-    @Override
-    public F getLast() {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Chain<F> getRest() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  @Immutable
-  @ParametersAreNonnullByDefault
-  private static final class NonEmptyChain<F> extends Chain<F> {
-    @Nonnegative final int numberOfElements;
-    @Nullable final F element;
-    @Nonnull final Chain<F> rest;
-
-    NonEmptyChain(@Nullable F element, Chain<F> rest) {
-      Preconditions.checkNotNull(rest);
-      this.numberOfElements = rest.size() + 1;
-      this.element = element;
-      this.rest = rest;
-    }
-
-    @Override
-    public int size() {
-      return numberOfElements;
-    }
-
-    @Override
-    public boolean isEmpty() {
-      return false;
-    }
-
-    @Override
-    @Nullable
-    public F getLast() {
-      return element;
-    }
-
-    @Override
-    @Nonnull
-    public Chain<F> getRest() {
-      return rest;
-    }
-  }
-
-  /**
-   * Adds a new element to the chain.  Since this is an immutable structure, a
-   * new chain is returned that contains the new element as well as all the
-   * elements of this chain.  The new chain has a "last" of {@code element} and
-   * a "rest" of {@code this}.
-   *
-   * @param element The element to be added.
-   * @return The new chain with the added element.
-   * @throws NullPointerException if element is null.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Chain<E> add(@Nullable E element) {
-    return new NonEmptyChain<E>(element, this);
-  }
-
-  /**
-   * Adds some new elements to the chain.
-   *
-   * @param elements The elements to be added.
-   * @return The new chain with the added elements.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Chain<E> addAll(Iterable<E> elements) {
-    Chain<E> chain = this;
-    for (E element : elements) {
-      chain = chain.add(element);
-    }
-    return chain;
-  }
-
-  /**
-   * Gets an element from the chain.  A given index specifies the
-   * element, where zero refers to the first element in the chain and
-   * {@code size() - 1} refers to the last.
-   *
-   * @param index The index of the element to get.
-   * @return The specified element.
-   * @throws IllegalArgumentException if index is negative or too large.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public E get(@Nonnegative int index) {
-    Preconditions.checkArgument(index >= 0 && index < size());
-    Chain<E> chain = this;
-    for (int i = 0; i < size() - (index + 1); i += 1) {
-      chain = chain.getRest();
-    }
-    return chain.getLast();
-  }
-
-  /**
-   * Converts this chain to a set.
-   *
-   * @return The elements of this chain as a set.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Set<E> toSet() {
-    return Sets.newHashSet(this);
-  }
-
-  /**
-   * Converts this chain to a list, preserving the chain's order.
-   *
-   * @return The elements of this chain as a list.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public List<E> toList() {
-    LinkedList<E> list = Lists.newLinkedList();
-    Chain<E> chain = this;
-    for (int i = 0; i < size(); i += 1) {
-      list.addFirst(chain.getLast());
-      chain = chain.getRest();
-    }
-    return list;
-  }
-
-  /**
-   * Given a chain that is an ancestor of this chain, returns the elements that
-   * have been added to the ancestor to make this chain.
-   *
-   * <p>For any ancestor chain {@code C} it is always true that
-   * {@code this.equals(C.addAll(this.toList(C)))}.
-   *
-   * @param ancestor The ancestor chain.
-   * @return A list of the elements elements added .
-   * @throws IllegalArgumentException if {@code chain} is not an ancestor.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public List<E> toList(Chain<E> ancestor) {
-    Preconditions.checkNotNull(ancestor);
-    LinkedList<E> list = Lists.newLinkedList();
-    Chain<E> chain = this;
-    while (chain != ancestor) {
-      if (chain.isEmpty()) {
-        throw new IllegalArgumentException("Not an ancestor chain: " + ancestor);
-      }
-      list.addFirst(chain.getLast());
-      chain = chain.getRest();
-    }
-    return list;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof Chain<?>)) { return false; }
-    Chain<?> other = (Chain<?>) object;
-    if (size() != other.size()) { return false; }
-    Chain<E> c1 = this;
-    Chain<?> c2 = other;
-    for (int i = 0; i < size(); i += 1) {
-      if (!c1.getLast().equals(c2.getLast())) { return false; }
-      c1 = c1.getRest();
-      c2 = c2.getRest();
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(toList());
-  }
-
-  @Override
-  public String toString() {
-    return toList().toString();
-  }
-
-  /**
-   * Gets an iterator for this chain.  The iterator starts with the last element
-   * and moves towards the first.  If you want to iterate from first element to
-   * last, use {@link #toList()}.
-   */
-  @Override
-  public Iterator<E> iterator() {
-    return new LocalIterator<E>(this);
-  }
-
-  @NotThreadSafe
-  private static final class LocalIterator<F> implements Iterator<F> {
-    Chain<F> chain;
-
-    LocalIterator(Chain<F> chain) {
-      this.chain = chain;
-    }
-
-    @Override
-    public boolean hasNext() {
-      return !chain.isEmpty();
-    }
-
-    @Override
-    public F next() {
-      if (chain.isEmpty()) { throw new NoSuchElementException(); }
-      F value = chain.getLast();
-      chain = chain.getRest();
-      return value;
-    }
-
-    @Override
-    public void remove() {
-      throw new UnsupportedOperationException();
-    }
-  }
-
-  /**
-   * Converts an iterable of chains to an iterable of lists.  The resulting
-   * lists have the same ordering as the input chains.
-   *
-   * @param chains The chains to convert.
-   * @return The resulting lists.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> Iterable<List<T>> toLists(Iterable<Chain<T>> chains) {
-    return Iterables.transform(chains, Chain.<T>toListFunction());
-  }
-
-  /**
-   * Gets a function that invokes the {@link #toList} method on its argument.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> Function<Chain<T>, List<T>> toListFunction() {
-    return new Function<Chain<T>, List<T>>() {
-      @Override
-      public List<T> apply(Chain<T> chain) {
-        return chain.toList();
-      }
-    };
-  }
-
-  /**
-   * Converts an iterable of chains to an iterable of sets.
-   *
-   * @param chains The chains to convert.
-   * @return The resulting sets.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> Iterable<Set<T>> toSets(Iterable<Chain<T>> chains) {
-    return Iterables.transform(chains, Chain.<T>toSetFunction());
-  }
-
-  /**
-   * Gets a function that invokes the {@link #toSet} method on its argument.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> Function<Chain<T>, Set<T>> toSetFunction() {
-    return new Function<Chain<T>, Set<T>>() {
-      @Override
-      public Set<T> apply(Chain<T> chain) {
-        return chain.toSet();
-      }
-    };
-  }
-
-  /**
-   * Extends an iterable of chains with a given element.  For each member of the
-   * iterable, it creates a new member by adding the element to that member.
-   *
-   * @param chains The chains to be extended.
-   * @param element The element to extend them with.
-   * @return An iterable of the extended chains.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> Iterable<Chain<T>> addToChains(Iterable<Chain<T>> chains, T element) {
-    return Iterables.transform(chains, addFunction(element));
-  }
-
-  /**
-   * Gets a function that adds a given element to a given chain.
-   *
-   * @param element The element to be added.
-   * @return A function that extends its argument with {@code element}.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> Function<Chain<T>, Chain<T>> addFunction(@Nullable final T element) {
-    return new Function<Chain<T>, Chain<T>>() {
-      @Override
-      public Chain<T> apply(Chain<T> chain) {
-        return chain.add(element);
-      }
-    };
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/CookieStore.java b/src/com/google/enterprise/secmgr/common/CookieStore.java
deleted file mode 100644
index 7664c7c..0000000
--- a/src/com/google/enterprise/secmgr/common/CookieStore.java
+++ /dev/null
@@ -1,86 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import java.util.Collection;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-
-/**
- * A cookie store is an object that holds a collection of cookies.  The store
- * never holds two cookies with the same key.  When a cookie is added to a
- * store, if there's already a cookie in the store with that key, the new cookie
- * replaces the old one.
- * <p>
- * Because of this, the store may contain multiple cookies with the same name,
- * as long as the other parts of their keys differ.
- */
-@ParametersAreNonnullByDefault
-public interface CookieStore extends Collection<GCookie> {
-  /**
-   * Removes all cookies with expiration times earlier than a given time.
-   *
-   * @param timeStamp A time to use for expirations.
-   */
-  public void expireCookies(@Nonnegative long timeStamp);
-
-  /**
-   * Removes all cookies with expiration times earlier than the current time.
-   */
-  public void expireCookies();
-
-  /**
-   * Does this store contain a cookie with a given name?
-   *
-   * @param name The name to test for.
-   * @return True only if there's at least one cookie with that name in the
-   *     store.
-   */
-  @CheckReturnValue
-  public boolean contains(String name);
-
-  /**
-   * If this store contains a cookie with a given name, gets it.  If there are
-   * multiple cookies with that name, one of them is arbitrarily chosen.
-   *
-   * @param name The name to look for.
-   * @return A cookie with that name, or {@code null} if there are none.
-   */
-  @CheckReturnValue
-  @Nullable
-  public GCookie get(String name);
-
-  /**
-   * Does this store contain a cookie with a given key?
-   *
-   * @param key The key to test for.
-   * @return True only if there's a cookie with that key in the store.
-   */
-  @CheckReturnValue
-  public boolean contains(GCookie.Key key);
-
-  /**
-   * If this store contains a cookie with a given key, gets it.
-   *
-   * @param key The key to look for.
-   * @return The cookie with that key, or {@code null} if there isn't one.
-   */
-  @CheckReturnValue
-  @Nullable
-  public GCookie get(GCookie.Key key);
-}
diff --git a/src/com/google/enterprise/secmgr/common/CookieStoreImpl.java b/src/com/google/enterprise/secmgr/common/CookieStoreImpl.java
deleted file mode 100644
index fbd4d32..0000000
--- a/src/com/google/enterprise/secmgr/common/CookieStoreImpl.java
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-
-import org.joda.time.DateTimeUtils;
-
-import java.util.AbstractCollection;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * An implementation of a mutable cookie store that automatically expires
- * cookies whenever a cookie is added or the store is iterated.
- */
-@NotThreadSafe
-@ParametersAreNonnullByDefault
-final class CookieStoreImpl extends AbstractCollection<GCookie>
-    implements CookieStore {
-
-  @Nonnull private final Map<GCookie.Key, GCookie> map;
-
-  CookieStoreImpl() {
-    map = Maps.newHashMap();
-  }
-
-  @Override
-  public int size() {
-    return map.size();
-  }
-
-  // For a given cookie name, a store can contain exactly one partial key with
-  // that name, or no partial keys and any number of full keys.
-  @Override
-  public boolean add(GCookie cookie) {
-    GCookie.Key key = cookie.getKey();
-    GCookie oldCookie = map.get(key);
-    if (cookie.equals(oldCookie)) {
-      return false;
-    }
-    Iterables.removeIf(this, matchingKeyPredicate(key));
-    if (oldCookie != null) {
-      map.put(key, GCookie.builder(cookie).setCreationTime(oldCookie.getCreationTime()).build());
-    } else {
-      map.put(key, cookie);
-    }
-    return true;
-  }
-
-  private static Predicate<GCookie> matchingKeyPredicate(final GCookie.Key key) {
-    return key.isPartial()
-      ? new Predicate<GCookie>() {
-          @Override
-          public boolean apply(GCookie cookie) {
-            GCookie.Key other = cookie.getKey();
-            return key.getName().equals(other.getName());
-          }
-        }
-      : new Predicate<GCookie>() {
-          @Override
-          public boolean apply(GCookie cookie) {
-            GCookie.Key other = cookie.getKey();
-            return key.getName().equals(other.getName())
-                && (other.isPartial() || key.equals(other));
-          }
-        };
-  }
-
-  @Override
-  public Iterator<GCookie> iterator() {
-    return map.values().iterator();
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof Iterable<?>)) { return false; }
-    return ImmutableSet.copyOf(map.values()).equals(ImmutableSet.copyOf((Iterable<?>) object));
-  }
-
-  @Override
-  public int hashCode() {
-    return ImmutableSet.copyOf(map.values()).hashCode();
-  }
-
-  @Override
-  public void expireCookies(@Nonnegative long timeStamp) {
-    Iterables.removeIf(this, GCookie.isExpiredPredicate(timeStamp));
-  }
-
-  @Override
-  public void expireCookies() {
-    expireCookies(DateTimeUtils.currentTimeMillis());
-  }
-
-  @Override
-  public boolean contains(String name) {
-    return get(name) != null;
-  }
-
-  @Override
-  @Nullable
-  public GCookie get(String name) {
-    Preconditions.checkNotNull(name);
-    for (GCookie cookie : map.values()) {
-      if (name.equalsIgnoreCase(cookie.getName())) {
-        return cookie;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public boolean contains(GCookie.Key key) {
-    return get(key) != null;
-  }
-
-  @Override
-  @Nullable
-  public GCookie get(GCookie.Key key) {
-    Preconditions.checkNotNull(key);
-    return map.get(key);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/FileUtil.java b/src/com/google/enterprise/secmgr/common/FileUtil.java
deleted file mode 100644
index 56ed934..0000000
--- a/src/com/google/enterprise/secmgr/common/FileUtil.java
+++ /dev/null
@@ -1,219 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.base.Preconditions;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- * Utilities for finding files.
- */
-public class FileUtil {
-
-  private static String contextDirectory;
-  private static String commonDirectory;
-
-  private static final String GOOGLE3_TEST_UTIL_CLASS = "com.google.testing.util.TestUtil";
-  private static final String GET_SRC_DIR_METHOD = "getSrcDir";
-  private static final String GET_TMP_DIR_METHOD = "getTmpDir";
-  private static final String GOOGLE3_TESTDATA_ROOT =
-      "/google3/javatests/com/google/enterprise/secmgr/testdata";
-  private static final String NON_GOOGLE3_TESTDATA_ROOT = "testdata/mocktestdata/";
-
-  private static final String BEGIN_PEM_CERTIFICATE_MARKER = "-----BEGIN CERTIFICATE-----";
-  private static final String END_PEM_CERTIFICATE_MARKER = "-----END CERTIFICATE-----";
-
-  // don't instantiate
-  private FileUtil() {
-  }
-
-  /**
-   * Initialize the context and common directories for testing.  Chooses appropriate
-   * values for them depending on the testing context.
-   */
-  public static void initializeTestDirectories() {
-    Class<?> clazz;
-    try {
-      clazz = Class.forName(GOOGLE3_TEST_UTIL_CLASS);
-    } catch (ClassNotFoundException e) {
-      // no worries -- this just means we're not in a google3 environment
-      contextDirectory = NON_GOOGLE3_TESTDATA_ROOT;
-      commonDirectory = NON_GOOGLE3_TESTDATA_ROOT;
-      return;
-    }
-
-    Method m1;
-    Method m2;
-    try {
-      m1 = clazz.getDeclaredMethod(GET_SRC_DIR_METHOD);
-      m2 = clazz.getDeclaredMethod(GET_TMP_DIR_METHOD);
-    } catch (NoSuchMethodException e) {
-      throw new IllegalStateException(e);
-    }
-
-    String srcDir;
-    String tmpDir;
-    try {
-      srcDir = String.class.cast(m1.invoke(null));
-      tmpDir = String.class.cast(m2.invoke(null));
-    } catch (IllegalAccessException e) {
-      throw new IllegalStateException(e);
-    } catch (InvocationTargetException e) {
-      throw new IllegalStateException(e);
-    }
-
-    contextDirectory = srcDir + GOOGLE3_TESTDATA_ROOT;
-    commonDirectory = tmpDir;
-  }
-
-  /**
-   * Get the context directory.  This directory holds the config files used by
-   * the security manager.
-   *
-   * @return The context directory as a string.
-   */
-  public static String getContextDirectory() {
-    return contextDirectory;
-  }
-
-  /**
-   * Get the common directory.  This directory holds all persistent state maintained by
-   * the connector manager.
-   *
-   * @return The common directory as a string.
-   */
-  public static String getCommonDirectory() {
-    // Allow override via command-line flags so that large tests can easily
-    // specify a tmp directory.
-    String testTmpDir = System.getProperty("google3.tmpdir");
-    if (testTmpDir != null) {
-      return testTmpDir;
-    }
-    return commonDirectory;
-  }
-
-  /**
-   * Set the Context/Common directory.  To be called only from the servlet
-   * initialization in a production environment.
-   */
-  public static void setContextDirectory(String directory) {
-    contextDirectory = directory;
-    commonDirectory = directory;
-  }
-
-  /**
-   * Resolve relative filenames in the directory of the config files.
-   *
-   * @param filename A (potentially relative) filename.
-   * @return An absolute File object.
-   */
-  public static File getContextFile(String filename) {
-    Preconditions.checkNotNull(filename);
-    return getContextFile(new File(filename));
-  }
-
-  /**
-   * Resolve relative filenames in the directory of the config files.
-   *
-   * @param file A (potentially relative) File object.
-   * @return An absolute File object.
-   */
-  public static File getContextFile(File file) {
-    Preconditions.checkNotNull(file);
-    return (file.isAbsolute()) ? file : new File(getContextDirectory(), file.toString());
-  }
-
-  /**
-   * Resolve relative filenames in the common directory.
-   *
-   * @param filename A (potentially relative) filename.
-   * @return An absolute File object.
-   * @see #getCommonDirectory
-   */
-  public static File getCommonFile(String filename) {
-    Preconditions.checkNotNull(filename);
-    return getCommonFile(new File(filename));
-  }
-
-  /**
-   * Resolve relative filenames in the common directory.
-   *
-   * @param file A (potentially relative) File object.
-   * @return An absolute File object.
-   * @see #getCommonDirectory
-   */
-  public static File getCommonFile(File file) {
-    Preconditions.checkNotNull(file);
-    return (file.isAbsolute()) ? file : new File(getCommonDirectory(), file.toString());
-  }
-
-  /**
-   * Read a file's contents and return them as a string.
-   *
-   * @param file The file to read.
-   * @return The file's contents.
-   * @throws IOException if unable to read the file.
-   */
-  public static String readFile(File file)
-      throws IOException {
-    Preconditions.checkNotNull(file);
-    StringBuffer accumulator = new StringBuffer();
-    char[] buffer = new char[4096];
-    Reader reader = null;
-    try {
-      reader = new FileReader(file);
-      while (true) {
-        int nRead = reader.read(buffer);
-        if (nRead < 0) {
-          break;
-        }
-        accumulator.append(buffer, 0, nRead);
-      }
-    } finally {
-      if (reader != null) {
-        reader.close();
-      }
-    }
-    return accumulator.toString();
-  }
-
-  /**
-   * Read a PEM-encoded certificate file and return the Base64 part as a string.
-   *
-   * @param file The file to read.
-   * @return The certificate in Base64 encoding.
-   * @throws IOException if unable to read or parse the file.
-   */
-  public static String readPEMCertificateFile(File file)
-      throws IOException {
-    String certFile = readFile(file);
-    int start = certFile.indexOf(BEGIN_PEM_CERTIFICATE_MARKER);
-    if (start < 0) {
-      throw new IOException("Certificate file missing begin marker");
-    }
-    start += BEGIN_PEM_CERTIFICATE_MARKER.length();
-    int end = certFile.indexOf(END_PEM_CERTIFICATE_MARKER, start);
-    if (end < 0) {
-      throw new IOException("Certificate file missing end marker");
-    }
-    return certFile.substring(start, end - 1);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/GCookie.java b/src/com/google/enterprise/secmgr/common/GCookie.java
deleted file mode 100644
index cd638ae..0000000
--- a/src/com/google/enterprise/secmgr/common/GCookie.java
+++ /dev/null
@@ -1,1873 +0,0 @@
-// Copyright 2011 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Splitter;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Maps;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-
-import org.joda.time.DateTimeUtils;
-
-import java.net.URI;
-import java.util.Calendar;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-import java.util.logging.Logger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.NotThreadSafe;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * An immutable cookie implementation that complies with RFC 6265.  Note that
- * this implementation does not (yet) support IDNA (RFC 5890) even though that
- * is required by the specification.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class GCookie {
-  private static final Logger LOGGER = Logger.getLogger(GCookie.class.getName());
-
-  // A cookie with its name in this list will always have its value logged in
-  // cleartext.
-  private static final ImmutableList<String> ALWAYS_SHOW_VALUE =
-      ImmutableList.of("GSA_SESSION_ID", "JSESSIONID");
-  private static final char OBFUSCATED_VALUE_PREFIX = '#';
-  private static final char VALUE_SEPARATOR = '=';
-  private static final char REQUEST_SEPARATOR = ';';
-  private static final String REQUEST_SEPARATOR_STRING = "; ";
-  private static final char ATTR_SEPARATOR = ';';
-  private static final String ATTR_SEPARATOR_STRING = "; ";
-  private static final char PATH_SEPARATOR = '/';
-  public static final String UNIVERSAL_PATH = "/";
-
-  private static final CharMatcher WSP = CharMatcher.anyOf(" \t");
-
-  /**
-   * Characters allowed in a cookie name.  Servers are supposed to restrict
-   * names to the HTTP token syntax.
-   */
-  private static final CharMatcher COOKIE_NAME = CharMatcher.noneOf(";=");
-
-  /**
-   * Characters allowed in a cookie value.  Servers are supposed to restrict
-   * values to octets between 0x21 and 0x7E inclusive, except for {@code '"'},
-   * {@code '\\'}, {@code ','}, and {@code ';'}.  The value may optionally be
-   * surrounded by double quotes.
-   */
-  private static final CharMatcher COOKIE_VALUE = CharMatcher.noneOf(";");
-
-  /**
-   * Cookies are distinguished by their name, their domain, and their path.  If
-   * two cookies have the same values for those elements, they are considered to
-   * be the same cookie.  This class formalizes that concept by providing an
-   * object representing the distinguishing components.
-   */
-  @Immutable
-  @ParametersAreNonnullByDefault
-  public static final class Key {
-    @Nonnull private final String name;
-    @Nonnull private final String domain;
-    @Nonnull private final String path;
-
-    private Key(String name, String domain, String path) {
-      this.name = name;
-      this.domain = domain;
-      this.path = path;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-      if (object == this) { return true; }
-      if (!(object instanceof Key)) { return false; }
-      Key other = (Key) object;
-      return getName().equalsIgnoreCase(other.getName())
-          && getDomain().equalsIgnoreCase(other.getDomain())
-          && getPath().equals(other.getPath());
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(name.toLowerCase(Locale.US), domain.toLowerCase(Locale.US), path);
-    }
-
-    // True only of cookies that didn't come from a set-cookie header.
-    boolean isPartial() {
-      return domain.isEmpty() && path.isEmpty();
-    }
-
-    /**
-     * Gets the name for this key.
-     *
-     * @return This key's name.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public String getName() {
-      return name;
-    }
-
-    /**
-     * Gets the domain for this key.
-     *
-     * @return This key's domain.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public String getDomain() {
-      return domain;
-    }
-
-    /**
-     * Gets the path for this key.
-     *
-     * @return This key's path.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public String getPath() {
-      return path;
-    }
-  }
-
-  @Nonnull private final Key key;
-  @Nonnull private final String value;
-  @Nonnegative private final long expires;
-  @Nonnegative private final long creationTime;
-  @Nonnegative private final long lastAccessTime;
-  private final boolean persistent;
-  private final boolean hostOnly;
-  private final boolean secureOnly;
-  private final boolean httpOnly;
-
-  private GCookie(Key key, String value, @Nonnegative long expires, @Nonnegative long creationTime,
-      @Nonnegative long lastAccessTime, boolean persistent, boolean hostOnly, boolean secureOnly,
-      boolean httpOnly) {
-    this.key = key;
-    this.value = value;
-    this.expires = expires;
-    this.creationTime = creationTime;
-    this.lastAccessTime = lastAccessTime;
-    this.persistent = persistent;
-    this.hostOnly = hostOnly;
-    this.secureOnly = secureOnly;
-    this.httpOnly = httpOnly;
-  }
-
-  // **************** Accessors ****************
-
-  /**
-   * Gets the cookie's key, an object that embodies what it means for two
-   * cookies to have the "same name".
-   *
-   * @return The key.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Key getKey() {
-    return key;
-  }
-
-  /**
-   * Gets the cookie's name, which is a non-empty case-insensitve string.
-   *
-   * @return The name.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String getName() {
-    return key.getName();
-  }
-
-  /**
-   * Gets the cookie's value.
-   *
-   * @return The value.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String getValue() {
-    return value;
-  }
-
-  /**
-   * Gets the cookie's expiration time in milliseconds from the epoch.
-   *
-   * @return The expiration time.
-   */
-  @CheckReturnValue
-  @Nonnegative
-  public long getExpires() {
-    return expires;
-  }
-
-  /**
-   * Gets the cookie's domain.
-   *
-   * @return The domain.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String getDomain() {
-    return key.getDomain();
-  }
-
-  /**
-   * Gets the cookie's path.
-   *
-   * @return The path.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String getPath() {
-    return key.getPath();
-  }
-
-  /**
-   * Gets the cookie's creation time in milliseconds from the epoch.
-   *
-   * @return The creation time.
-   */
-  @CheckReturnValue
-  @Nonnegative
-  public long getCreationTime() {
-    return creationTime;
-  }
-
-  /**
-   * Gets the cookie's last-access time in milliseconds from the epoch.
-   *
-   * @return The last-access time.
-   */
-  @CheckReturnValue
-  @Nonnegative
-  public long getLastAccessTime() {
-    return lastAccessTime;
-  }
-
-  /**
-   * Is the cookie persistent?
-   *
-   * @return True if the cookie is persistent.
-   */
-  @CheckReturnValue
-  public boolean getPersistent() {
-    return persistent;
-  }
-
-  /**
-   * Should this cookie be restricted to the host that exactly matches its domain?
-   *
-   * @return True if the cookie should be restricted.
-   */
-  @CheckReturnValue
-  public boolean getHostOnly() {
-    return hostOnly;
-  }
-
-  /**
-   * Is the cookie valid only for "secure" connections?
-   *
-   * @return True if the cookie is usable only for HTTPS and other secure
-   *     connections.
-   */
-  @CheckReturnValue
-  public boolean getSecureOnly() {
-    return secureOnly;
-  }
-
-  /**
-   * Should the cookie be restricted to HTTP messages?  If true, Javascript
-   * client programs can't access this cookie.
-   *
-   * @return True if the cookie should be restricted.
-   */
-  @CheckReturnValue
-  public boolean getHttpOnly() {
-    return httpOnly;
-  }
-
-  /**
-   * Is this cookie expired?
-   *
-   * @param timeStamp The reference time at which to determine the answer.
-   * @return True if the cookie is expired.
-   */
-  @CheckReturnValue
-  public boolean isExpired(@Nonnegative long timeStamp) {
-    Preconditions.checkArgument(timeStamp >= 0);
-    return getExpires() <= timeStamp;
-  }
-
-  /**
-   * Gets a predicate that computes {@link #isExpired}.
-   *
-   * @param timeStamp The reference time at which to determine the answer.
-   * @return A predicate that's true if a given cookie is expired at the
-   *     reference time.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<GCookie> isExpiredPredicate(@Nonnegative final long timeStamp) {
-    Preconditions.checkArgument(timeStamp >= 0);
-    return new Predicate<GCookie>() {
-      @Override
-      public boolean apply(GCookie cookie) {
-        return cookie.getExpires() <= timeStamp;
-      }
-    };
-  }
-
-  /**
-   * Gets the "maximum age" of this cookie.  Normally this isn't used; it's provided
-   * for compatibility.  Instead use {@link #getExpires}.
-   *
-   * @return The "maximum age" of this cookie in seconds, or {@code -1} for a
-   *     session cookie.
-   */
-  @CheckReturnValue
-  public int getMaxAge() {
-    if (!getPersistent()) {
-      return -1;
-    }
-    if (getExpires() < getCreationTime()) {
-      return 0;
-    }
-    long deltaSeconds = ((getExpires() - getCreationTime()) + 500) / 1000;
-    return (deltaSeconds > Integer.MAX_VALUE)
-        ? -1
-        : (int) deltaSeconds;
-  }
-
-  // **************** Equality ****************
-
-  /** Note that equality doesn't consider any of the cookie's times. */
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof GCookie)) { return false; }
-    GCookie other = (GCookie) object;
-    return getKey().equals(other.getKey())
-        && getValue().equals(other.getValue())
-        && getPersistent() == other.getPersistent()
-        && getSecureOnly() == other.getSecureOnly()
-        && getHttpOnly() == other.getHttpOnly();
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(getKey(), getValue(), getPersistent(), getSecureOnly(), getHttpOnly());
-  }
-
-  /**
-   * Checks whether a given cookie has the same name as this cookie.
-   *
-   * @param cookie The cookie to compare against.
-   * @return True only if the names match.
-   */
-  @CheckReturnValue
-  public boolean hasSameName(GCookie cookie) {
-    return getName().equalsIgnoreCase(cookie.getName());
-  }
-
-  /**
-   * Checks whether any of some given cookies have the same name as this cookie.
-   *
-   * @param cookies The cookies to compare against.
-   * @return True only if the name of one of the cookies matches.
-   */
-  @CheckReturnValue
-  public boolean hasSameName(Iterable<GCookie> cookies) {
-    for (GCookie cookie : cookies) {
-      if (hasSameName(cookie)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Checks whether a given cookie has the same key as this cookie.
-   *
-   * @param cookie The cookie to compare against.
-   * @return True only if the keys match.
-   */
-  @CheckReturnValue
-  public boolean hasSameKey(GCookie cookie) {
-    return getKey().equals(cookie.getKey());
-  }
-
-  /**
-   * Checks whether any of some given cookies have the same key as this cookie.
-   *
-   * @param cookies The cookies to compare against.
-   * @return True only if the key of one of the cookies matches.
-   */
-  @CheckReturnValue
-  public boolean hasSameKey(Iterable<GCookie> cookies) {
-    for (GCookie cookie : cookies) {
-      if (hasSameKey(cookie)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  // **************** Logging support ****************
-
-  @Override
-  public String toString() {
-    return responseHeaderString(false);
-  }
-
-  /**
-   * Generates a log message containing a description of some given cookies in
-   * request format.
-   *
-   * @param prefix A prefix for the log message.
-   * @param cookies The cookies to be described.
-   * @return A suitably formatted log message.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static String requestCookiesMessage(String prefix, Iterable<GCookie> cookies) {
-    StringBuilder builder = new StringBuilder();
-    builder.append(prefix);
-    builder.append(": ");
-    if (Iterables.isEmpty(cookies)) {
-      builder.append("(none)");
-    } else {
-      writeRequest(cookies, false, builder);
-    }
-    return builder.toString();
-  }
-
-  /**
-   * Generates a log message containing a description of some given cookies in
-   * response format.
-   *
-   * @param prefix A prefix for the log message.
-   * @param cookies The cookies to be described.
-   * @return A suitably formatted log message.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static String responseCookiesMessage(String prefix, Iterable<GCookie> cookies) {
-    StringBuilder builder = new StringBuilder();
-    builder.append(prefix);
-    builder.append(": ");
-    if (Iterables.isEmpty(cookies)) {
-      builder.append("(none)");
-    } else {
-      boolean needSeparator = false;
-      for (GCookie cookie : cookies) {
-        if (needSeparator) {
-          builder.append(", ");
-        } else {
-          needSeparator = true;
-        }
-        cookie.writeResponse(false, builder);
-      }
-    }
-    return builder.toString();
-  }
-
-  // **************** URI filtering ****************
-
-  /**
-   * Checks if this cookie is suitable for a given target URI.
-   *
-   * @param uri The URI object to test against.
-   * @return True if the cookie is suitable to be sent to the URI.
-   */
-  @CheckReturnValue
-  public boolean isGoodFor(URI uri) {
-    return domainMatch(getDomain(), getHostOnly(), computeRequestHost(uri))
-        && pathMatch(getPath(), uri.getPath())
-        && secureOnlyMatch(getSecureOnly(), uri.getScheme());
-  }
-
-  private static boolean domainMatch(String cookieDomain, boolean hostOnly, String requestHost) {
-    if (cookieDomain.isEmpty()) {
-      return true;
-    }
-    requestHost = requestHost.toLowerCase(Locale.US);
-    if (requestHost.equals(cookieDomain)) {
-      return true;
-    }
-    if (hostOnly) {
-      return false;
-    }
-    return requestHost.endsWith(cookieDomain)
-        && requestHost.charAt(requestHost.length() - cookieDomain.length() - 1) == '.';
-  }
-
-  private static boolean pathMatch(String cookiePath, String requestPath) {
-    return cookiePath.isEmpty()
-        || requestPath.equals(cookiePath)
-        || (requestPath.startsWith(cookiePath)
-            && (lastChar(cookiePath) == PATH_SEPARATOR
-                || requestPath.charAt(cookiePath.length()) == PATH_SEPARATOR));
-  }
-
-  private static char firstChar(String string) {
-    return string.charAt(0);
-  }
-
-  private static char lastChar(String string) {
-    return string.charAt(string.length() - 1);
-  }
-
-  private static boolean secureOnlyMatch(boolean secureOnly, String requestProtocol) {
-    return !secureOnly || "https".equalsIgnoreCase(requestProtocol);
-  }
-
-  /**
-   * Determine whether there are any cookies to send.
-   *
-   * @param uri The URI of the authority.
-   * @param userAgentCookies The cookies received from the user agent.
-   * @param authorityCookies The cookies previously received from the authority.
-   * @return True if there are some cookies to be sent.
-   */
-  @CheckReturnValue
-  public static boolean haveCookiesToSend(URI uri, Iterable<GCookie> userAgentCookies,
-      Iterable<GCookie> authorityCookies) {
-    return anyCookieGoodFor(userAgentCookies, uri)
-        || anyCookieGoodFor(authorityCookies, uri);
-  }
-
-  private static boolean anyCookieGoodFor(Iterable<GCookie> cookies, URI uri) {
-    for (GCookie cookie : cookies) {
-      if (cookie.isGoodFor(uri)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Compute the cookies to send to a given authority.  Authority cookies have
-   * priority over user-agent cookies.
-   *
-   * @param uri The URI of the authority.
-   * @param userAgentCookies The cookies received from the user agent.
-   * @param authorityCookies The cookies previously received from the authority.
-   * @param store The cookie store to add the "to-send" cookies to.
-   */
-  public static void computeCookiesToSend(URI uri, Iterable<GCookie> userAgentCookies,
-      Iterable<GCookie> authorityCookies, CookieStore store) {
-    for (GCookie cookie : authorityCookies) {
-      if (cookie.isGoodFor(uri)) {
-        store.add(cookie);
-      }
-    }
-    for (GCookie cookie : userAgentCookies) {
-      if (cookie.isGoodFor(uri) && !store.contains(cookie.getName())) {
-        store.add(cookie);
-      }
-    }
-  }
-
-  /**
-   * Compute the cookies to send to a given authority.  Authority cookies have
-   * priority over user-agent cookies.
-   *
-   * @param uri The URI of the authority.
-   * @param userAgentCookies The cookies received from the user agent.
-   * @param authorityCookies The cookies previously received from the authority.
-   * @return A cookie store containing the "to-send" cookies.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static CookieStore computeCookiesToSend(URI uri,
-      Iterable<GCookie> userAgentCookies, Iterable<GCookie> authorityCookies) {
-    CookieStore store = makeStore();
-    computeCookiesToSend(uri, userAgentCookies, authorityCookies, store);
-    store.expireCookies();
-    return store;
-  }
-
-  // **************** Cookie store ****************
-
-  /**
-   * Makes a new empty store.
-   *
-   * @return A new empty store.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static CookieStore makeStore() {
-    return new CookieStoreImpl();
-  }
-
-  /**
-   * Makes a new store and adds some cookies to it.
-   *
-   * @param cookies The cookies to be added.
-   * @return A new store containing the given cookies.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static CookieStore makeStore(Iterable<GCookie> cookies) {
-    CookieStore store = makeStore();
-    Iterables.addAll(store, cookies);
-    store.expireCookies();
-    return store;
-  }
-
-  /**
-   * Merge two collections of cookies together.
-   *
-   * @param cookies1 The first collection.
-   * @param cookies2 The second collection, which overrides the first.
-   * @return The merged collection.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Iterable<GCookie> mergeCookies(Iterable<GCookie> cookies1,
-      Iterable<GCookie> cookies2) {
-    CookieStore store = makeStore();
-    Iterables.addAll(store, cookies1);
-    Iterables.addAll(store, cookies2);
-    store.expireCookies();
-    return store;
-  }
-
-  // **************** Conversions to/from Java cookies ****************
-
-  /**
-   * Converts a cookie to a {@link GCookie}.
-   *
-   * @param cookie A cookie to be converted.
-   * @return The converted cookie.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static GCookie fromCookie(Cookie cookie) {
-    return builder(cookie).build();
-  }
-
-  /**
-   * Converts this {@link GCookie} to a {@link Cookie}.
-   *
-   * @return A newly created {@link Cookie}.
-   * @throws RuntimeException if unable to perform the conversion.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public Cookie toCookie() {
-    Cookie cookie = new Cookie(getName(), getValue());
-    cookie.setValue(getValue());
-    if (getDomain() != null) {
-      cookie.setDomain(getDomain());
-    }
-    cookie.setPath(getPath());
-    cookie.setSecure(getSecureOnly());
-    cookie.setMaxAge(getMaxAge());
-    return cookie;
-  }
-
-  /**
-   * Converts some {@link GCookie}s to {@link Cookie}s.
-   *
-   * @param cookies The cookies to be converted.
-   * @return The converted cookies, except for those that fail to convert.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static ImmutableList<Cookie> toCookie(Iterable<GCookie> cookies) {
-    ImmutableList.Builder<Cookie> builder = ImmutableList.builder();
-    for (GCookie cookie : cookies) {
-      Cookie c;
-      try {
-        c = cookie.toCookie();
-      } catch (RuntimeException e) {
-        continue;
-      }
-      builder.add(c);
-    }
-    return builder.build();
-  }
-
-  // **************** Generating HTTP headers ****************
-
-  /**
-   * Gets a string representing the given cookies in request format.
-   *
-   * @param cookies The cookies to convert.
-   * @param showValues If false, the cookie's value will be obfuscated in the
-   *     returned string.
-   * @return The formatted string.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static String requestHeaderString(Iterable<GCookie> cookies,
-      boolean showValues) {
-    StringBuilder builder = new StringBuilder();
-    writeRequest(cookies, showValues, builder);
-    return builder.toString();
-  }
-
-  /**
-   * Writes a representation of the given cookies in request format.
-   *
-   * @param cookies The cookies to write.
-   * @param showValues If false, the cookie's value will be obfuscated in the
-   *     returned string.
-   * @param builder A string builder to write the representation to.
-   */
-  public static void writeRequest(Iterable<GCookie> cookies, boolean showValues,
-      StringBuilder builder) {
-    boolean needSeparator = false;
-    for (GCookie cookie : cookies) {
-      if (needSeparator) {
-        builder.append(REQUEST_SEPARATOR_STRING);
-      } else {
-        needSeparator = true;
-      }
-      cookie.writeRequest(showValues, builder);
-    }
-  }
-
-  /**
-   * Gets a string representing this cookie in request format.
-   *
-   * @param showValues If false, the cookie's value will be obfuscated in the
-   *     returned string.
-   * @return The formatted string.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String requestHeaderString(boolean showValues) {
-    StringBuilder builder = new StringBuilder();
-    writeRequest(showValues, builder);
-    return builder.toString();
-  }
-
-  /**
-   * Writes a representation of this cookie in request format.
-   *
-   * @param showValues If false, the cookie's value will be obfuscated in the
-   *     returned string.
-   * @param builder A string builder to write the representation to.
-   */
-  public void writeRequest(boolean showValues, StringBuilder builder) {
-    writeBinding(showValues, builder);
-  }
-
-  /**
-   * Gets a string representing this cookie in response format.
-   *
-   * @param showValues If false, the cookie's value will be obfuscated in the
-   *     returned string.
-   * @return The formatted string.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String responseHeaderString(boolean showValues) {
-    StringBuilder builder = new StringBuilder();
-    writeResponse(showValues, builder);
-    return builder.toString();
-  }
-
-  /**
-   * Writes a representation of this cookie in response format.
-   *
-   * @param showValues If false, the cookie's value will be obfuscated in the
-   *     returned string.
-   * @param builder A string builder to write the representation to.
-   */
-  public void writeResponse(boolean showValues, StringBuilder builder) {
-    writeBinding(showValues, builder);
-    if (getExpires() < Long.MAX_VALUE) {
-      writeAttr(AttrName.EXPIRES, HttpUtil.generateHttpDate(getExpires()), builder);
-    }
-    writeAttr(AttrName.MAX_AGE, getMaxAge(), builder);
-    if (!(getHostOnly() || getDomain().isEmpty())) {
-      String domain = getDomain();
-      if (!domain.startsWith(".")) {
-        domain = "." + domain;
-      }
-      writeAttr(AttrName.DOMAIN, domain, builder);
-    }
-    writeAttr(AttrName.PATH, getPath(), builder);
-    writeAttr(AttrName.SECURE, getSecureOnly(), builder);
-    writeAttr(AttrName.HTTP_ONLY, getHttpOnly(), builder);
-  }
-
-  private void writeBinding(boolean showValues, StringBuilder builder) {
-    builder.append(getName());
-    builder.append(VALUE_SEPARATOR);
-    if (!getValue().isEmpty()) {
-      if (showValues || alwaysShowValue(getName())) {
-        builder.append(getValue());
-      } else {
-        builder.append(OBFUSCATED_VALUE_PREFIX);
-        builder.append(
-            Base64.encodeWebSafe(SecurePasswordHasher.macInput(getName(), getValue()), false));
-      }
-    }
-  }
-
-  private static void writeAttr(AttrName param, String value, StringBuilder builder) {
-    if (!value.isEmpty()) {
-      builder.append(ATTR_SEPARATOR_STRING);
-      builder.append(param.toString());
-      builder.append(VALUE_SEPARATOR);
-      builder.append(value);
-    }
-  }
-
-  private static void writeAttr(AttrName param, int value, StringBuilder builder) {
-    if (value >= 0) {
-      writeAttr(param, Integer.toString(value), builder);
-    }
-  }
-
-  private static void writeAttr(AttrName param, boolean value, StringBuilder builder) {
-    if (value) {
-      builder.append(ATTR_SEPARATOR_STRING);
-      builder.append(param.toString());
-    }
-  }
-
-  private static boolean alwaysShowValue(String name) {
-    for (String name2 : ALWAYS_SHOW_VALUE) {
-      if (name2.equalsIgnoreCase(name)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  private enum AttrName {
-    EXPIRES("Expires"),
-    MAX_AGE("Max-Age"),
-    DOMAIN("Domain"),
-    PATH("Path"),
-    SECURE("Secure"),
-    HTTP_ONLY("HttpOnly");
-
-    @Nonnull private final String name;
-
-    private AttrName(String name) {
-      this.name = name;
-    }
-
-    @Override
-    public String toString() {
-      return name;
-    }
-  }
-
-  // **************** Parsers ****************
-
-  /**
-   * Parses request header values to produce cookies.  Returns Java cookies for
-   * use by legacy code.
-   *
-   * @param headers The header values to parse.
-   * @return An immutable list of the parsed cookies.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static ImmutableList<Cookie> legacyParseRequestHeaders(Iterable<String> headers) {
-    CookieStore store = makeStore();
-    parseRequestHeaders(headers, null, null, store);
-    return toCookie(store);
-  }
-
-  /**
-   * Parses request header values to produce cookies.
-   *
-   * @param headers The header values to parse.
-   * @param requestUri The request URI.
-   * @param sessionId A session ID to add to log messages.
-   * @param store A cookie store to which the parsed cookies will be added.
-   */
-  public static void parseRequestHeaders(Iterable<String> headers, URI requestUri, String sessionId,
-      CookieStore store) {
-    long now = DateTimeUtils.currentTimeMillis();
-    for (String header : headers) {
-      for (String cookiePair : REQUEST_SPLITTER.split(header)) {
-        Builder builder;
-        try {
-          builder = parseCookiePair(cookiePair, now);
-        } catch (ParseException e) {
-          LOGGER.info(SecurityManagerUtil.sessionLogMessage(sessionId, e.getMessage()));
-          continue;
-        }
-        store.add(builder.build());
-      }
-    }
-    store.expireCookies(now);
-  }
-
-  /**
-   * Parses response header values to produce cookies.
-   *
-   * @param headers The header values to parse.
-   * @param requestUri The request URI corresponding to this response.
-   * @param sessionId A session ID to add to log messages.
-   * @param store A cookie store to which the parsed cookies will be added.
-   */
-  public static void parseResponseHeaders(Iterable<String> headers, URI requestUri,
-      String sessionId, CookieStore store) {
-    long now = DateTimeUtils.currentTimeMillis();
-    for (String header : headers) {
-      GCookie cookie;
-      try {
-        cookie = parseResponseHeader(header, requestUri, now);
-      } catch (ParseException e) {
-        LOGGER.info(SecurityManagerUtil.sessionLogMessage(sessionId, e.getMessage()));
-        continue;
-      }
-      store.add(cookie);
-    }
-    store.expireCookies(now);
-  }
-
-  private static GCookie parseResponseHeader(String header, URI requestUri, long now)
-      throws ParseException {
-    List<String> parts = ImmutableList.copyOf(ATTR_SPLITTER.split(header));
-    if (parts.isEmpty()) {
-      parseError("No value separator in: %s", Stringify.object(header));
-    }
-    Builder builder = parseCookiePair(parts.get(0), now)
-        .setCreationTime(now)
-        .setLastAccessTime(now);
-    Map<AttrName, Object> parsedAttrs = parseAttrs(parts.subList(1, parts.size()));
-
-    Long maxAgeRaw = Long.class.cast(parsedAttrs.get(AttrName.MAX_AGE));
-    if (maxAgeRaw != null) {
-      long maxAge = maxAgeRaw.longValue();
-      long expires;
-      if (maxAge <= 0) {
-        expires = 0;
-      } else {
-        expires = now + maxAge;
-        if (expires < 0) {
-          // Means we got an overflow.
-          expires = Long.MAX_VALUE;
-        }
-      }
-      builder.setPersistent(true);
-      builder.setExpires(expires);
-    } else {
-      Long expiresRaw = Long.class.cast(parsedAttrs.get(AttrName.EXPIRES));
-      if (expiresRaw != null) {
-        long expires = expiresRaw.longValue();
-        if (expires >= 0) {
-          builder.setPersistent(true);
-          builder.setExpires(expires);
-        } else {
-          builder.setPersistent(false);
-          builder.setExpires(Long.MAX_VALUE);
-        }
-      }
-    }
-
-    if (requestUri != null) {
-      String requestHost = computeRequestHost(requestUri);
-      String domain = String.class.cast(parsedAttrs.get(AttrName.DOMAIN));
-      if (domain == null) {
-        domain = "";
-      }
-      if (isPublicSuffix(domain)) {
-        if (!domain.equals(requestHost)) {
-          parseError("Cookie domain %s is a public domain",
-              Stringify.object(domain));
-        }
-        domain = "";
-      }
-      if (domain.isEmpty()) {
-        builder.setHostOnly(true);
-        builder.setDomain(requestHost);
-      } else {
-        if (!domainMatch(domain, false, requestHost)) {
-          parseError("Cookie domain %s doesn't match request host %s",
-              Stringify.object(domain), Stringify.object(requestHost));
-        }
-        builder.setHostOnly(false);
-        builder.setDomain(domain);
-      }
-
-      String path = String.class.cast(parsedAttrs.get(AttrName.PATH));
-      if (path == null || path.isEmpty()) {
-        builder.setPath(computeDefaultPath(requestUri));
-      } else {
-        builder.setPath(path);
-      }
-    }
-
-    builder.setSecureOnly(parsedAttrs.get(AttrName.SECURE) != null);
-    builder.setHttpOnly(parsedAttrs.get(AttrName.HTTP_ONLY) != null);
-
-    return builder.build();
-  }
-
-  private static Builder parseCookiePair(String cookiePair, long now)
-      throws ParseException {
-    int vsep = cookiePair.indexOf(VALUE_SEPARATOR);
-    if (vsep < 0) {
-      parseError("No value separator in: %s",
-          Stringify.object(cookiePair));
-    }
-    String name = WSP.trimFrom(cookiePair.substring(0, vsep));
-    if (!isCookieName(name)) {
-      parseError("Invalid cookie name %s in: %s",
-          Stringify.object(name), Stringify.object(cookiePair));
-    }
-    String value = WSP.trimFrom(cookiePair.substring(vsep + 1));
-    if (!isCookieValue(value)) {
-      parseError("Invalid cookie value %s in: %s",
-          Stringify.object(value), Stringify.object(cookiePair));
-    }
-    return builder(name, now).setValue(value);
-  }
-
-  private static final Splitter REQUEST_SPLITTER =
-      Splitter.on(REQUEST_SEPARATOR).trimResults().omitEmptyStrings();
-
-  private static final Splitter ATTR_SPLITTER =
-      Splitter.on(ATTR_SEPARATOR).trimResults().omitEmptyStrings();
-
-  private static Map<AttrName, Object> parseAttrs(List<String> unparsedAttrs) {
-    Map<AttrName, Object> parsedAttrs = Maps.newHashMap();
-    for (String unparsed : unparsedAttrs) {
-      String aname;
-      String avalue;
-      int vsep = unparsed.indexOf(VALUE_SEPARATOR);
-      if (vsep < 0) {
-        aname = WSP.trimFrom(unparsed);
-        avalue = "";
-      } else {
-        aname = WSP.trimFrom(unparsed.substring(0, vsep));
-        avalue = WSP.trimFrom(unparsed.substring(vsep + 1));
-      }
-      AttrName attrName = findAttrName(aname);
-      if (attrName != null) {
-        Object value = dispatchAttr(attrName, avalue);
-        if (value != null) {
-          parsedAttrs.put(attrName, value);
-        }
-      }
-    }
-    return parsedAttrs;
-  }
-
-  private static AttrName findAttrName(String aname) {
-    for (AttrName attrName : EnumSet.allOf(AttrName.class)) {
-      if (attrName.toString().equalsIgnoreCase(aname)) {
-        return attrName;
-      }
-    }
-    return null;
-  }
-
-  private static Object dispatchAttr(AttrName attrName, String avalue) {
-    switch (attrName) {
-      case EXPIRES: return parseExpires(avalue);
-      case MAX_AGE: return parseMaxAge(avalue);
-      case DOMAIN: return parseDomain(avalue);
-      case PATH: return parsePath(avalue);
-      case SECURE: return parseSecure(avalue);
-      case HTTP_ONLY: return parseHttpOnly(avalue);
-      default: throw new IllegalStateException("Unknown AttrName: " + attrName);
-    }
-  }
-
-  private static Long parseExpires(String expires) {
-    try {
-      return parseDate(expires);
-    } catch (IllegalArgumentException e) {
-      LOGGER.info("Error parsing Expires attribute: " + e.getMessage());
-      return null;
-    }
-  }
-
-  private static Long parseMaxAge(String maxAge) {
-    try {
-      return Long.parseLong(maxAge);
-    } catch (NumberFormatException e) {
-      return null;
-    }
-  }
-
-  private static String parseDomain(String domain) {
-    return domain.isEmpty() ? null : canonicalizeDomain(domain);
-  }
-
-  private static String canonicalizeDomain(String domain) {
-    if (domain.startsWith(".")) {
-      domain = domain.substring(1);
-    }
-    try {
-      // Do full canonicalization if possible.
-      return HttpUtil.canonicalizeDomainName(domain);
-    } catch (IllegalArgumentException e) {
-      // Otherwise fall back to simple case folding.
-      return domain.toLowerCase(Locale.US);
-    }
-  }
-
-  private static boolean isPublicSuffix(String domain) {
-    // TODO(cph): should check for "public suffix" here.  See
-    // <http://publicsuffix.org/>.
-    return false;
-  }
-
-  private static String parsePath(String path) {
-    return (path.isEmpty() || firstChar(path) != PATH_SEPARATOR)
-        ? ""
-        : path;
-  }
-
-  private static boolean parseSecure(String avalue) {
-    return true;
-  }
-
-  private static boolean parseHttpOnly(String avalue) {
-    return true;
-  }
-
-  private static String computeRequestHost(URI requestUri) {
-    String host = requestUri.getHost();
-    try {
-      return HttpUtil.canonicalizeDomainName(host);
-    } catch (IllegalArgumentException e) {
-      return host.toLowerCase(Locale.US);
-    }
-  }
-
-  private static String computeDefaultPath(URI requestUri) {
-    String path = requestUri.getPath();
-    if (path.isEmpty() || firstChar(path) != PATH_SEPARATOR) {
-      return UNIVERSAL_PATH;
-    }
-    int lastSeparator = path.lastIndexOf(PATH_SEPARATOR);
-    return (lastSeparator > 0)
-        ? path.substring(0, lastSeparator)
-        : UNIVERSAL_PATH;
-  }
-
-  private static String parseError(String format, Object... args)
-      throws ParseException {
-    throw new ParseException(String.format(format, args));
-  }
-
-  /**
-   * An exception that's thrown by a cookie parser when the input can't be
-   * parsed.
-   */
-  public static final class ParseException extends Exception {
-    ParseException(String message) { super(message); }
-  }
-
-  // **************** Element predicates and canonicalizers ****************
-
-  /**
-   * Is the given string a valid cookie name?
-   *
-   * @param name The string to test.
-   * @return True only if the given string can be used as a cookie's name.
-   */
-  @CheckReturnValue
-  public static boolean isCookieName(String name) {
-    return !name.isEmpty()
-        && COOKIE_NAME.matchesAllOf(name)
-        && noLeadingOrTrailingWhitespace(name);
-  }
-
-  /**
-   * Is the given string a valid cookie value?
-   *
-   * @param value The string to test.
-   * @return True only if the given string can be used as a cookie's value.
-   */
-  @CheckReturnValue
-  public static boolean isCookieValue(String value) {
-    return value.isEmpty()
-        || (COOKIE_VALUE.matchesAllOf(value)
-            && noLeadingOrTrailingWhitespace(value));
-  }
-
-  private static boolean noLeadingOrTrailingWhitespace(String string) {
-    return !WSP.matches(string.charAt(0))
-        && !WSP.matches(string.charAt(string.length() - 1));
-  }
-
-  // **************** Date parser ****************
-
-  @VisibleForTesting
-  static long parseDate(String string) {
-    int[] hms = null;
-    int dayOfMonth = -1;
-    int month = -1;
-    int year = -1;
-    for (String token : tokenizeDate(string)) {
-      if (hms == null) {
-        hms = parseTimeToken(token);
-        if (hms != null) {
-          continue;
-        }
-      }
-      if (dayOfMonth < 0) {
-        dayOfMonth = parseDayOfMonthToken(token);
-        if (dayOfMonth >= 0) {
-          continue;
-        }
-      }
-      if (month < 0) {
-        month = parseMonthToken(token);
-        if (month >= 0) {
-          continue;
-        }
-      }
-      if (year < 0) {
-        year = parseYearToken(token);
-      }
-    }
-    if (year >= 0 && year < 70) {
-      year += 2000;
-    } else if (year >= 70 && year < 100) {
-      year += 1900;
-    }
-    String message = null;
-    if (hms == null) {
-      message = "no time seen";
-    } else if (hms[0] > 23) {
-      message = String.format("hour too large: %d", hms[0]);
-    } else if (hms[1] > 59) {
-      message = String.format("minute too large: %d", hms[1]);
-    } else if (hms[2] > 59) {
-      message = String.format("second too large: %d", hms[2]);
-    } else if (dayOfMonth < 0) {
-      message = "no day of month seen";
-    } else if (dayOfMonth == 0 || dayOfMonth > 31) {
-      message = String.format("illegal day of month: %d", dayOfMonth);
-    } else if (month < 0) {
-      message = "no month seen";
-    } else if (year < 0) {
-      message = "no year seen";
-    } else if (year < 1601) {
-      message = String.format("year too small: %d", year);
-    }
-    if (message != null) {
-      throw new IllegalArgumentException(parseDateMessage(message, string));
-    }
-    Calendar calendar = Calendar.getInstance(GMT, Locale.US);
-    calendar.setLenient(false);
-    calendar.set(year, month, dayOfMonth, hms[0], hms[1], hms[2]);
-    try {
-      return calendar.getTimeInMillis();
-    } catch (IllegalArgumentException e) {
-      throw new IllegalArgumentException(parseDateMessage(e.getMessage(), string));
-    }
-  }
-
-  private static List<String> tokenizeDate(String string) {
-    ImmutableList.Builder<String> listBuilder = ImmutableList.builder();
-    StringBuilder tokenBuilder = null;
-    for (int i = 0; i < string.length(); i += 1) {
-      char c = string.charAt(i);
-      if (DATE_DELIMITER.matches(c)) {
-        if (tokenBuilder != null) {
-          listBuilder.add(tokenBuilder.toString());
-          tokenBuilder = null;
-        }
-      } else {
-        if (tokenBuilder == null) {
-          tokenBuilder = new StringBuilder();
-        }
-        tokenBuilder.append(c);
-      }
-    }
-    if (tokenBuilder != null) {
-      listBuilder.add(tokenBuilder.toString());
-    }
-    return listBuilder.build();
-  }
-
-  private static final CharMatcher DATE_DELIMITER =
-      CharMatcher.is('\t')
-      .or(CharMatcher.inRange('\u0020', '\u002F'))
-      .or(CharMatcher.inRange('\u003B', '\u0040'))
-      .or(CharMatcher.inRange('\u005B', '\u0060'))
-      .or(CharMatcher.inRange('\u007B', '\u007E'));
-
-  private static int[] parseTimeToken(String token) {
-    Matcher m = applyPattern(TIME_PATTERN, token);
-    if (m == null) {
-      return null;
-    }
-    int[] hms = new int[3];
-    hms[0] = Integer.valueOf(m.group(1));
-    hms[1] = Integer.valueOf(m.group(2));
-    hms[2] = Integer.valueOf(m.group(3));
-    return hms;
-  }
-
-  private static final Pattern TIME_PATTERN =
-      Pattern.compile("([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})");
-
-  private static int parseDayOfMonthToken(String token) {
-    Matcher m = applyPattern(DAY_OF_MONTH_PATTERN, token);
-    return (m != null) ? Integer.valueOf(m.group()) : -1;
-  }
-
-  private static final Pattern DAY_OF_MONTH_PATTERN = Pattern.compile("[0-9]{1,2}");
-
-  private static int parseMonthToken(String token) {
-    if (token.length() < 3) {
-      return -1;
-    }
-    String p = token.substring(0, 3);
-    for (Map.Entry<String, Integer> entry : MONTHS.entrySet()) {
-      if (entry.getKey().equalsIgnoreCase(p)) {
-        return entry.getValue();
-      }
-    }
-    return -1;
-  }
-
-  private static final Map<String, Integer> MONTHS;
-  static {
-    ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
-    builder.put("jan", Calendar.JANUARY);
-    builder.put("feb", Calendar.FEBRUARY);
-    builder.put("mar", Calendar.MARCH);
-    builder.put("apr", Calendar.APRIL);
-    builder.put("may", Calendar.MAY);
-    builder.put("jun", Calendar.JUNE);
-    builder.put("jul", Calendar.JULY);
-    builder.put("aug", Calendar.AUGUST);
-    builder.put("sep", Calendar.SEPTEMBER);
-    builder.put("oct", Calendar.OCTOBER);
-    builder.put("nov", Calendar.NOVEMBER);
-    builder.put("dec", Calendar.DECEMBER);
-    MONTHS = builder.build();
-  }
-
-  private static int parseYearToken(String token) {
-    Matcher m = applyPattern(YEAR_PATTERN, token);
-    return (m != null) ? Integer.valueOf(m.group()) : -1;
-  }
-
-  private static final Pattern YEAR_PATTERN = Pattern.compile("[0-9]{2,4}");
-
-  private static Matcher applyPattern(Pattern pattern, String token) {
-    Matcher m = pattern.matcher(token);
-    if (m.lookingAt()) {
-      int end = m.end();
-      if (end == token.length() || !HttpUtil.DIGIT.matches(token.charAt(end))) {
-        return m;
-      }
-    }
-    return null;
-  }
-
-  private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
-
-  private static String parseDateMessage(String message, String string) {
-    return String.format("Can't parse date string because %s: %s",
-        message, Stringify.object(string));
-  }
-
-  // **************** Constructor ****************
-
-  /**
-   * Gets a {@link GCookie} with just a name and a value.
-   *
-   * @param name The name of the cookie to build.
-   * @param value The value of the cookie to build.
-   * @return A {@link GCookie}.
-   * @throws IllegalArgumentException if {@code name} doesn't satisfy
-   *     {@link #isCookieName} or if {@code value} doesn't satisfy
-   *     {@link #isCookieValue}.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static GCookie make(String name, String value) {
-    return builder(name).setValue(value).build();
-  }
-
-  /**
-   * Gets a builder for constructing a {@link GCookie}.
-   *
-   * @param name The name of the cookie to build.
-   * @return A {@link GCookie} builder.
-   * @throws IllegalArgumentException if {@code name} doesn't satisfy
-   *     {@link #isCookieName}.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Builder builder(String name) {
-    return new Builder(name, DateTimeUtils.currentTimeMillis());
-  }
-
-  /**
-   * Gets a builder for constructing a {@link GCookie}.
-   *
-   * @param name The name of the cookie to build.
-   * @param now The current time in milliseconds since the epoch.
-   * @return A {@link GCookie} builder.
-   * @throws IllegalArgumentException if {@code name} doesn't satisfy
-   *     {@link #isCookieName} or if {@code now} is negative.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Builder builder(String name, long now) {
-    return new Builder(name, now);
-  }
-
-  /**
-   * Gets a builder for constructing a {@link GCookie}.
-   *
-   * @param key The key of the cookie to build.
-   * @return A {@link GCookie} builder.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Builder builder(Key key) {
-    return builder(key.getName())
-        .setDomain(key.getDomain())
-        .setPath(key.getPath());
-  }
-
-  /**
-   * Gets a builder for constructing a {@link GCookie}.
-   *
-   * @param cookie A cookie to use to pre-populate the builder.
-   * @return A {@link GCookie} builder.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Builder builder(Cookie cookie) {
-    return builder(cookie.getName()).setFromCookie(cookie);
-  }
-
-  /**
-   * Gets a builder for constructing a {@link GCookie}.
-   *
-   * @param cookie A cookie to use to pre-populate the builder.
-   * @return A {@link GCookie} builder.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Builder builder(GCookie cookie) {
-    return builder(cookie.getName()).setFromCookie(cookie);
-  }
-
-  /**
-   * A builder class for {@link GCookie} instances.
-   */
-  @NotThreadSafe
-  @ParametersAreNonnullByDefault
-  public static final class Builder {
-    @Nonnull private final String name;
-    @Nonnegative private final long now;
-    @Nonnull private String value = "";
-    private long expires = -1;
-    @Nonnull private String domain = "";
-    @Nonnull private String path = "";
-    private long creationTime = -1;
-    private long lastAccessTime = -1;
-    private boolean persistent = false;
-    private boolean hostOnly = false;
-    private boolean secureOnly = false;
-    private boolean httpOnly = false;
-    private boolean maxAgeSet = false;
-    private long maxAge;
-
-    private Builder(String name, @Nonnegative long now) {
-      Preconditions.checkArgument(isCookieName(name),
-          "Illegal name: %s", name);
-      Preconditions.checkArgument(now >= 0,
-          "Illegal time: %s", now);
-      this.name = name;
-      this.now = now;
-    }
-
-    /**
-     * Builds the cookie using the parameters accumulated by the builder.
-     *
-     * @return A newly created {@link GCookie}.
-     */
-    @CheckReturnValue
-    @Nonnull
-    public GCookie build() {
-      long at = computeLastAccessTime();
-      long ct = computeCreationTime(at);
-      return new GCookie(new Key(name, domain, path), value, computeExpires(ct), ct, at,
-          computePersistent(), hostOnly, secureOnly, httpOnly);
-    }
-
-    // The following computations assume that:
-    // 1. If maxAgeSet is true, maxAge is preferred to expires and persistent.
-    // 2. creationTime is either negative or <= now.
-    // 3. lastAccessTime is either negative or <= now.
-    // 4. When finished, creationTime <= lastAccessTime.
-
-    private long computeLastAccessTime() {
-      return (lastAccessTime < 0) ? now : lastAccessTime;
-    }
-
-    private long computeCreationTime(long lastAccessTime) {
-      return (creationTime < 0 || lastAccessTime < creationTime)
-          ? lastAccessTime
-          : creationTime;
-    }
-
-    private long computeExpires(long creationTime) {
-      return maxAgeSet
-          ? ((maxAge < 0) ? Long.MAX_VALUE : creationTime + (maxAge * 1000))
-          : ((expires < 0) ? Long.MAX_VALUE : expires);
-    }
-
-    private boolean computePersistent() {
-      return maxAgeSet ? (maxAge >= 0) : persistent;
-    }
-
-    /**
-     * Sets the value of the {@link GCookie} being built.
-     *
-     * @param value The value.
-     * @return This builder, for convenience.
-     * @throws IllegalArgumentException if {@code value} doesn't satisfy
-     *     {@link #isCookieValue}.
-     */
-    @Nonnull
-    public Builder setValue(String value) {
-      Preconditions.checkArgument(isCookieValue(value),
-          "Illegal value: %s", value);
-      this.value = value;
-      return this;
-    }
-
-    /**
-     * Sets the expiration time of the {@link GCookie} being built.
-     *
-     * @param expires The expiration time.
-     * @return This builder, for convenience.
-     * @throws IllegalArgumentException if the argument is invalid.
-     */
-    @Nonnull
-    public Builder setExpires(@Nonnegative long expires) {
-      Preconditions.checkArgument(expires >= 0,
-          "Illegal expires: %s", expires);
-      this.expires = expires;
-      return this;
-    }
-
-    /**
-     * Sets the maximum age of the {@link GCookie} being built.  Translates this
-     * age into the "expires" and "persistent" attributes of the resulting
-     * cookie.
-     *
-     * @param maxAge The maximum age in seconds.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setMaxAge(long maxAge) {
-      this.maxAge = maxAge;
-      maxAgeSet = true;
-      return this;
-    }
-
-    /**
-     * Sets the domain of the {@link GCookie} being built.
-     *
-     * @param domain The domain.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setDomain(String domain) {
-      this.domain = canonicalizeDomain(domain);
-      return this;
-    }
-
-    /**
-     * Sets the path of the {@link GCookie} being built.
-     *
-     * @param path The path.
-     * @return This builder, for convenience.
-     * @throws IllegalArgumentException if the argument is invalid.
-     */
-    @Nonnull
-    public Builder setPath(String path) {
-      Preconditions.checkArgument(path.isEmpty() || firstChar(path) == PATH_SEPARATOR,
-          "Illegal path: %s", path);
-      this.path = path;
-      return this;
-    }
-
-    /**
-     * Sets the creation time of the {@link GCookie} being built.
-     *
-     * @param creationTime The creation time.
-     * @return This builder, for convenience.
-     * @throws IllegalArgumentException if the argument is invalid.
-     */
-    @Nonnull
-    public Builder setCreationTime(@Nonnegative long creationTime) {
-      Preconditions.checkArgument(creationTime >= 0 && creationTime <= now,
-          "Illegal creation time: %s", creationTime);
-      this.creationTime = creationTime;
-      return this;
-    }
-
-    /**
-     * Sets the last-access time of the {@link GCookie} being built.
-     *
-     * @param lastAccessTime The last-access time.
-     * @return This builder, for convenience.
-     * @throws IllegalArgumentException if the argument is invalid.
-     */
-    @Nonnull
-    public Builder setLastAccessTime(@Nonnegative long lastAccessTime) {
-      Preconditions.checkArgument(lastAccessTime >= 0 && lastAccessTime <= now,
-          "Illegal last-access time: %s", lastAccessTime);
-      this.lastAccessTime = lastAccessTime;
-      return this;
-    }
-
-    /**
-     * Sets whether the {@link GCookie} being built is persistent.
-     *
-     * @param persistent True if the cookie is persistent.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setPersistent(boolean persistent) {
-      this.persistent = persistent;
-      return this;
-    }
-
-    /**
-     * Sets whether the {@link GCookie} being built is restricted to "secure"
-     * connections.
-     *
-     * @param secureOnly True if the cookie is restricted.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setSecureOnly(boolean secureOnly) {
-      this.secureOnly = secureOnly;
-      return this;
-    }
-
-    /**
-     * Sets whether the {@link GCookie} being built is restricted to the host
-     * that exactly matches its domain.
-     *
-     * @param hostOnly True if the cookie is restricted.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setHostOnly(boolean hostOnly) {
-      this.hostOnly = hostOnly;
-      return this;
-    }
-
-    /**
-     * Sets whether the {@link GCookie} being built should be restricted to the
-     * HTTP messages.  In other words, if true, Javascript client programs can't
-     * access this cookie.
-     *
-     * @param httpOnly If true, the cookie should be restricted.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setHttpOnly(boolean httpOnly) {
-      this.httpOnly = httpOnly;
-      return this;
-    }
-
-    /**
-     * Sets the fields of the {@link GCookie} being built by copying them from a
-     * given cookie.  All fields in the given cookie, other than the name and
-     * value, are copied to the new {@link GCookie}.
-     *
-     * @param cookie The cookie to copy them from.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setFromCookie(Cookie cookie) {
-      setValue(cookie.getValue());
-      setMaxAge(cookie.getMaxAge());
-      setDomain(cookie.getDomain());
-      setPath(cookie.getPath());
-      setSecureOnly(cookie.getSecure());
-      return this;
-    }
-
-    /**
-     * Sets the fields of the {@link GCookie} being built by copying them from a
-     * given cookie.  All fields in the given cookie, other than the name and
-     * value, are copied to the new {@link GCookie}.
-     *
-     * @param cookie The cookie to copy them from.
-     * @return This builder, for convenience.
-     */
-    @Nonnull
-    public Builder setFromCookie(GCookie cookie) {
-      setValue(cookie.getValue());
-      setExpires(cookie.getExpires());
-      setDomain(cookie.getDomain());
-      setPath(cookie.getPath());
-      setCreationTime(cookie.getCreationTime());
-      setLastAccessTime(cookie.getLastAccessTime());
-      setPersistent(cookie.getPersistent());
-      setHostOnly(cookie.getHostOnly());
-      setSecureOnly(cookie.getSecureOnly());
-      setHttpOnly(cookie.getHttpOnly());
-      return this;
-    }
-  }
-
-  // **************** Interface with HTTP request/response ****************
-
-  /**
-   * Parses cookies from the headers of an HTTP request.
-   *
-   * @param request The request to get the headers from.
-   * @param sessionId A session ID to add to log messages.
-   * @param store A cookie store to which the parsed cookies will be added.
-   */
-  public static void parseHttpRequestCookies(HttpServletRequest request, String sessionId,
-      CookieStore store) {
-    parseRequestHeaders(
-        HttpUtil.getRequestHeaderValues(HttpUtil.HTTP_HEADER_COOKIE, request),
-        HttpUtil.getRequestUri(request, false),
-        sessionId,
-        store);
-  }
-
-  /**
-   * Parses cookies from the headers of an HTTP request.
-   *
-   * @param request The request to get the headers from.
-   * @param sessionId A session ID to add to log messages.
-   * @return A cookie store containing the parsed cookies.
-   */
-  public static CookieStore parseHttpRequestCookies(HttpServletRequest request, String sessionId) {
-    CookieStore store = makeStore();
-    parseHttpRequestCookies(request, sessionId, store);
-    return store;
-  }
-
-  /**
-   * Adds a cookie to an HTTP response.
-   *
-   * @param cookie The cookie to add.
-   * @param response The response to save the cookie header in.
-   */
-  public static void addHttpResponseCookie(GCookie cookie, HttpServletResponse response) {
-    response.addCookie(cookie.toCookie());
-    response.addHeader(HttpUtil.HTTP_HEADER_SET_COOKIE, cookie.responseHeaderString(true));
-  }
-
-  /**
-   * Adds cookies to an HTTP response.
-   *
-   * @param cookies The cookies to add.
-   * @param response The response to save the cookie headers in.
-   */
-  public static void addHttpResponseCookies(Iterable<GCookie> cookies,
-      HttpServletResponse response) {
-    for (GCookie cookie : cookies) {
-      addHttpResponseCookie(cookie, response);
-    }
-  }
-
-  // **************** JSON ****************
-
-  public static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(GCookie.class,
-        ProxyTypeAdapter.make(GCookie.class, GCookie.LocalProxy.class));
-  }
-
-  private static final class LocalProxy implements TypeProxy<GCookie> {
-    String name;
-    String value;
-    long expires;
-    String domain;
-    String path;
-    long creationTime;
-    long lastAccessTime;
-    boolean persistent;
-    boolean hostOnly;
-    boolean secureOnly;
-    boolean httpOnly;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(GCookie cookie) {
-      name = cookie.getName();
-      value = cookie.getValue();
-      expires = cookie.getExpires();
-      domain = cookie.getDomain();
-      path = cookie.getPath();
-      creationTime = cookie.getCreationTime();
-      lastAccessTime = cookie.getLastAccessTime();
-      persistent = cookie.getPersistent();
-      hostOnly = cookie.getHostOnly();
-      secureOnly = cookie.getSecureOnly();
-      httpOnly = cookie.getHttpOnly();
-    }
-
-    @Override
-    public GCookie build() {
-      return builder(name)
-          .setValue(value)
-          .setExpires(expires)
-          .setDomain(domain)
-          .setPath(path)
-          .setCreationTime(creationTime)
-          .setLastAccessTime(lastAccessTime)
-          .setPersistent(persistent)
-          .setHostOnly(hostOnly)
-          .setSecureOnly(secureOnly)
-          .setHttpOnly(httpOnly)
-          .build();
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/HttpUtil.java b/src/com/google/enterprise/secmgr/common/HttpUtil.java
deleted file mode 100644
index 0aab54c..0000000
--- a/src/com/google/enterprise/secmgr/common/HttpUtil.java
+++ /dev/null
@@ -1,825 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.base.CharMatcher;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Splitter;
-import com.google.common.base.Strings;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.ListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-
-import org.springframework.mock.web.MockHttpServletRequest;
-
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.text.DateFormat;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.TimeZone;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * Static methods for fetching pages via HTTP.  See RFCs 2616 and 2617 for
- * details.
- */
-public final class HttpUtil {
-
-  public static final String HTTP_METHOD_GET = "GET";
-  public static final String HTTP_METHOD_POST = "POST";
-  public static final String HTTP_METHOD_HEAD = "HEAD";
-
-  // HTTP header names.
-  public static final String HTTP_HEADER_ACCEPT = "Accept";
-  public static final String HTTP_HEADER_ACCEPT_CHARSET = "Accept-Charset";
-  public static final String HTTP_HEADER_ACCEPT_ENCODING = "Accept-Encoding";
-  public static final String HTTP_HEADER_ACCEPT_LANGUAGE = "Accept-Language";
-  public static final String HTTP_HEADER_AUTHORIZATION = "Authorization";
-  public static final String HTTP_HEADER_CONNECTION = "Connection";
-  public static final String HTTP_HEADER_CONTENT_LENGTH = "Content-Length";
-  public static final String HTTP_HEADER_COOKIE = "Cookie";
-  public static final String HTTP_HEADER_DATE = "Date";
-  public static final String HTTP_HEADER_LOCATION = "Location";
-  public static final String HTTP_HEADER_PROXY_AUTHENTICATE = "Proxy-Authenticate";
-  public static final String HTTP_HEADER_PROXY_AUTHORIZATION = "Proxy-Authorization";
-  public static final String HTTP_HEADER_RANGE = "Range";
-  public static final String HTTP_HEADER_SET_COOKIE = "Set-Cookie";
-  public static final String HTTP_HEADER_SET_COOKIE2 = "Set-Cookie2";
-  public static final String HTTP_HEADER_USER_AGENT = "User-Agent";
-  public static final String HTTP_HEADER_WWW_AUTHENTICATE = "WWW-Authenticate";
-
-  // TODO(kstillson): The rest of this file is general purpose http, but
-  // this cookie-cracking code is quite security manager specific.  At some
-  // point, it would be good to refactor (perhaps providing a caller
-  // specified callback for custom header processing?)
-  //
-  // TODO(kstillson): make this extensible/configurable (at least from spring).
-  // These are Google-specific headers set in a response, which can set the
-  // username and groups list for a credentials group.
-  public static final String COOKIE_CRACK_USERNAME_HEADER = "X-Username";
-  public static final String COOKIE_CRACK_GROUPS_HEADER = "X-Groups";
-
-  // Boilerplate HTTP header values.
-  public static final String KEEP_ALIVE = "keep-alive";
-  // TODO(michellez): make this configurable through spring.
-  public static final String USER_AGENT = "SecMgr";
-  public static final String ACCEPT =
-      "text/html, text/xhtml;q=0.9, text/plain;q=0.5, text/*;q=0.1";
-  public static final String ACCEPT_FOR_HEAD = "*/*";
-  public static final String ACCEPT_CHARSET = "us-ascii, iso-8859-1, utf-8";
-  public static final String ACCEPT_ENCODING = "identity";
-  public static final String ACCEPT_LANGUAGE = "en-us, en;q=0.9";
-  private static final String RANGE_FORMAT = "bytes=0-%d";
-
-  public static final char PARAM_VALUE_SEPARATOR = '=';
-  public static final char STRING_DELIMITER = '"';
-  public static final char STRING_QUOTE = '\\';
-  public static final char PARAM_SEPARATOR_CHAR = ';';
-  public static final String PARAM_SEPARATOR = "; ";
-
-  // Don't instantiate.
-  private HttpUtil() {
-    throw new UnsupportedOperationException();
-  }
-
-  public static boolean isHttpGetMethod(String method) {
-    return HTTP_METHOD_GET.equalsIgnoreCase(method);
-  }
-
-  public static boolean isHttpPostMethod(String method) {
-    return HTTP_METHOD_POST.equalsIgnoreCase(method);
-  }
-
-  public static boolean isHttpHeadMethod(String method) {
-    return HTTP_METHOD_HEAD.equalsIgnoreCase(method);
-  }
-
-  /*
-  // Commented out to prevent pulling in ServletBase.
-  public static List<StringPair> getBoilerplateHeaders() {
-    return getBoilerplateHeaders(false);
-  }
-
-  public static List<StringPair> getBoilerplateHeaders(boolean isHeadRequest) {
-    String accept = isHeadRequest ? ACCEPT_FOR_HEAD : ACCEPT;
-    return ImmutableList.of(
-        new StringPair(HTTP_HEADER_ACCEPT, accept),
-        new StringPair(HTTP_HEADER_ACCEPT_CHARSET, ACCEPT_CHARSET),
-        new StringPair(HTTP_HEADER_ACCEPT_ENCODING, ACCEPT_ENCODING),
-        new StringPair(HTTP_HEADER_ACCEPT_LANGUAGE, ACCEPT_LANGUAGE),
-        new StringPair(HTTP_HEADER_DATE, ServletBase.httpDateString()));
-  }*/
-
-  /**
-   * Does the given HTTP status code indicate a valid response?
-   *
-   * @param status The status code to test.
-   * @return True only if it indicates a valid response.
-   */
-  public static boolean isGoodHttpStatus(int status) {
-    return status == HttpServletResponse.SC_OK
-        || status == HttpServletResponse.SC_PARTIAL_CONTENT;
-  }
-
-  public static URL urlFromString(String urlString) {
-    try {
-      return new URL(urlString);
-    } catch (MalformedURLException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  public static URL urlFromString(URL baseUrl, String urlString) {
-    try {
-      return new URL(baseUrl, urlString);
-    } catch (MalformedURLException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  public static URL urlFromParts(String protocol, String host, int port, String file) {
-    try {
-      return new URL(protocol, host, port, file);
-    } catch (MalformedURLException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  public static URL parseUrlString(String urlString) {
-    try {
-      return new URL(urlString);
-    } catch (MalformedURLException e) {
-      return null;
-    }
-  }
-
-  public static URL parseUrlString(URL baseUrl, String urlString) {
-    try {
-      return new URL(baseUrl, urlString);
-    } catch (MalformedURLException e) {
-      return null;
-    }
-  }
-
-  public static URL parentUrl(URL url) {
-    String path = url.getPath();
-    int slash = path.lastIndexOf('/');
-    if (slash <= 0) {
-      return null;
-    }
-    return urlFromParts(url.getProtocol(), url.getHost(), url.getPort(), path.substring(0, slash));
-  }
-
-  public static URL stripQueryFromUrl(URL url) {
-    return mergeQueryIntoUrl(url, null);
-  }
-
-  public static URL mergeQueryIntoUrl(URL url, String query) {
-    return urlFromParts(url.getProtocol(), url.getHost(), url.getPort(),
-        newQuery(url.getPath(), query));
-  }
-
-  private static String newQuery(String path, String query) {
-    return Strings.isNullOrEmpty(query) ? path : path + "?" + query;
-  }
-
-  /**
-   * Converts a {@link URL} to a {@link URI}.
-   *
-   * @param url The URL to convert.
-   * @return The corresponding URI.
-   * @throws IllegalArgumentException if there are any parse errors in the
-   *     conversion.
-   */
-  public static URI toUri(URL url) {
-    return URI.create(url.toString());
-  }
-
-  /**
-   * Takes a given URI and returns a new one in which the query component has
-   * been replaced with a given query string.
-   *
-   * @param uri The base URI.
-   * @param query The new query component; may be {@code null} to delete the
-   *     query component.
-   * @return A suitably modified URI.
-   */
-  public static URI replaceUriQuery(URI uri, String query) {
-    try {
-      return new URI(uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
-          uri.getPath(), query, uri.getFragment());
-    } catch (URISyntaxException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  /**
-   * Decodes an application/x-www-form-urlencoded format query string into its
-   * component parameters.
-   *
-   * @param uri A URI to decode the query string of.
-   * @return A multimap containing the decoded parameters from the uri.
-   * @throws IllegalArgumentException if the URI's query isn't correctly formatted.
-   */
-  public static ListMultimap<String, String> decodeQueryString(URI uri) {
-    return decodeQueryString(uri.getQuery());
-  }
-
-  /**
-   * Decodes an application/x-www-form-urlencoded format query string into its
-   * component parameters.
-   *
-   * @param string The query string to decode.
-   * @return A multimap containing the decoded parameters from the string.
-   * @throws IllegalArgumentException if the string isn't correctly formatted.
-   */
-  public static ListMultimap<String, String> decodeQueryString(String string) {
-    ListMultimap<String, String> result = ArrayListMultimap.create();
-    if (!Strings.isNullOrEmpty(string)) {
-      for (String element : QUERY_SPLITTER.split(string)) {
-        int index = element.indexOf('=');
-        if (index < 0) {
-          result.put(element, null);
-        } else {
-          result.put(element.substring(0, index), element.substring(index + 1));
-        }
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Encodes a multimap of query parameters in application/x-www-form-urlencoded
-   * format.
-   *
-   * @param parameters The query parameters to be encoded.
-   * @return The encoded string.
-   */
-  public static String encodeQueryString(Multimap<String, String> parameters) {
-    StringBuilder builder = new StringBuilder();
-    boolean needSeparator = false;
-    for (Map.Entry<String, String> entry : parameters.entries()) {
-      if (needSeparator) {
-        builder.append('&');
-      } else {
-        needSeparator = true;
-      }
-      builder.append(entry.getKey());
-      if (entry.getValue() != null) {
-        builder.append('=');
-        builder.append(entry.getValue());
-      }
-    }
-    return builder.toString();
-  }
-
-  private static final Splitter QUERY_SPLITTER = Splitter.on('&');
-
-  /**
-   * Gets the URI for an HTTP request.
-   *
-   * @param request The HTTP request to get the URI from.
-   * @param includeQuery If true, include the query part of the URI.
-   * @return The request URI.
-   * @throws IllegalArgumentException if the request's URI can't be parsed.
-   */
-  public static URI getRequestUri(HttpServletRequest request, boolean includeQuery) {
-    URI uri = (request instanceof MockHttpServletRequest)
-        ? getMockRequestUri((MockHttpServletRequest) request)
-        : URI.create(request.getRequestURL().toString());
-    return includeQuery
-        ? uri
-        : replaceUriQuery(uri, null);
-  }
-
-  private static URI getMockRequestUri(MockHttpServletRequest request) {
-    // Note that it's not OK to call request.getRequestURL() because the mock
-    // implementation is broken and will include ":-1" if there's no port
-    // specified.
-    try {
-      return new URI(request.getScheme(), null, request.getServerName(), request.getServerPort(),
-          request.getRequestURI(), request.getQueryString(), null);
-    } catch (URISyntaxException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  /**
-   * Gets the URL for an HTTP request.
-   *
-   * @param request The HTTP request to get the URL from.
-   * @param includeQuery If true, include the query part of the URL.
-   * @return The request URL.
-   * @throws IllegalArgumentException if the request's URL can't be parsed.
-   */
-  public static URL getRequestUrl(HttpServletRequest request, boolean includeQuery) {
-    try {
-      return getRequestUri(request, includeQuery).toURL();
-    } catch (MalformedURLException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  /**
-   * Given a URL, gets a string suitable for logging.  This string omits the URL
-   * query, as it might contain sensitive parameters that shouldn't be logged
-   * (e.g. a password).  It also omits the fragment identifier, since that isn't
-   * usually needed in the log.
-   *
-   * @param url The URL to get a log string for.
-   * @return An appropriate string representation of the URL.
-   */
-  public static String getUrlLogString(URL url) {
-    return getUriLogString(toUri(url));
-  }
-
-  /**
-   * Given a URL string, gets a string suitable for logging.  This string omits
-   * the URL query, as it might contain sensitive parameters that shouldn't be
-   * logged (e.g. a password).  It also omits the fragment identifier, since
-   * that isn't usually needed in the log.
-   *
-   * @param urlString The URL string to get a log string for.
-   * @return An appropriate string representation of the URL.
-   */
-  public static String getUrlLogString(String urlString) {
-    URI uri;
-    try {
-      uri = new URI(urlString);
-    } catch (URISyntaxException e) {
-      // Dumb, but in the unlikely event we get the exception, it should serve.
-      int index = urlString.indexOf('?');
-      return (index >= 0)
-          ? urlString.substring(0, index)
-          : urlString;
-    }
-    return getUriLogString(uri);
-  }
-
-  /**
-   * Given a URI, gets a string suitable for logging.  This string omits the URI
-   * query, as it might contain sensitive parameters that shouldn't be logged
-   * (e.g. a password).  It also omits the fragment identifier, since that isn't
-   * usually needed in the log.
-   *
-   * @param uri The URI to get a log string for.
-   * @return An appropriate string representation of the URL.
-   */
-  public static String getUriLogString(URI uri) {
-    try {
-      return (new URI(uri.getScheme(), uri.getAuthority(), uri.getPath(), null, null))
-          .toASCIIString();
-    } catch (URISyntaxException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  /**
-   * Gets the header value strings for any headers matching a given name.
-   *
-   * @param name The header name to look for.
-   * @param request The request to look in.
-   * @return The header values as an immutable list.
-   */
-  public static ImmutableList<String> getRequestHeaderValues(String name,
-      HttpServletRequest request) {
-    ImmutableList.Builder<String> builder = ImmutableList.builder();
-    Enumeration<?> e = request.getHeaders(name);
-    while (e.hasMoreElements()) {
-      builder.add(String.class.cast(e.nextElement()));
-    }
-    return builder.build();
-  }
-
-  /**
-   * Parse an HTTP header parameter.  Parameters come in two forms:
-   *
-   * token PARAM_VALUE_SEPARATOR token
-   * token PARAM_VALUE_SEPARATOR quoted-string
-   *
-   * The character set for a "token" is restricted.  A "quoted-string" is
-   * surrounded by double quotes and can contain nearly all characters, plus
-   * escaped characters.
-   *
-   * @param string The raw parameter string, assumed to have been trimmed of whitespace.
-   * @return A list of two strings, the name and the value.
-   * @throws IllegalArgumentException if the string can't be parsed.
-   */
-  public static List<String> parseHttpParameter(String string) {
-    int equals = string.indexOf(PARAM_VALUE_SEPARATOR);
-    checkParameterArgument(equals >= 0, string);
-    String name = string.substring(0, equals);
-    checkParameterArgument(isHttpToken(name), string);
-    String rawValue = string.substring(equals + 1, string.length());
-    return ImmutableList.of(name,
-        isHttpToken(rawValue) ? rawValue : parseHttpQuotedString(rawValue));
-  }
-
-  private static void checkParameterArgument(boolean succeed, String argument) {
-    Preconditions.checkArgument(succeed, "Incorrectly formatted HTTP parameter: %s", argument);
-  }
-
-  /**
-   * Is the given string an HTTP token?
-   *
-   * @param string The string to test.
-   * @return True if the string is a valid HTTP token.
-   */
-  public static boolean isHttpToken(String string) {
-    return !Strings.isNullOrEmpty(string) && TOKEN.matchesAllOf(string);
-  }
-
-  /**
-   * Is the given string something that can be encoded as an HTTP quoted-string?
-   *
-   * @param string The string to test.
-   * @return True if the string can be encoded using the quoted-string format.
-   */
-  public static boolean isQuotedStringEncodable(String string) {
-    return string != null && TEXT.matchesAllOf(string);
-  }
-
-  /**
-   * Encodes a string so that it's suitable as an HTTP parameter value.  In
-   * other words, if the string is an HTTP token, it's self encoding.
-   * Otherwise, it is converted to the quoted-string format.
-   *
-   * @param string The string to be encoded.
-   * @return The same string encoded as an HTTP parameter value.
-   * @throws IllegalArgumentException if the given string can't be encoded.
-   */
-  public static String makeHttpParameterValueString(String string) {
-    if (isHttpToken(string)) {
-      return string;
-    }
-    StringBuilder builder = new StringBuilder();
-    writeQuotedString(string, builder);
-    return builder.toString();
-  }
-
-  /**
-   * Writes a string-valued HTTP parameter to a given string builder.  The
-   * parameter is prefixed by {@link #PARAM_SEPARATOR}.
-   *
-   * @param name The parameter name, which must satisfy {@link #isHttpToken}.
-   * @param value The parameter value, which must satisfy
-   *     {@link #isQuotedStringEncodable}.
-   * @param builder A string builder to write the parameter to.
-   * @throws IllegalArgumentException if {@code name} or {@code value} can't be
-   *     encoded.
-   */
-  public static void writeParameter(String name, String value, StringBuilder builder) {
-    writeParameterName(name, builder);
-    builder.append(PARAM_VALUE_SEPARATOR);
-    writeParameterValue(value, builder);
-  }
-
-  /**
-   * Writes a boolean-valued HTTP parameter to a given string builder.  The
-   * parameter is prefixed by {@link #PARAM_SEPARATOR}.
-   *
-   * @param name The parameter name, which must satisfy {@link #isHttpToken}.
-   * @param value The parameter value.
-   * @param builder A string builder to write the parameter to.
-   * @throws IllegalArgumentException if {@code name} can't be encoded.
-   */
-  public static void writeParameter(String name, boolean value, StringBuilder builder) {
-    if (value) {
-      writeParameterName(name, builder);
-    }
-  }
-
-  /**
-   * Writes an HTTP parameter name to a given string builder.  The name is
-   * prefixed by {@link #PARAM_SEPARATOR}.
-   *
-   * @param name The parameter name, which must satisfy {@link #isHttpToken}.
-   * @param builder A string builder to write the name to.
-   * @throws IllegalArgumentException if {@code name} can't be encoded.
-   */
-  public static void writeParameterName(String name, StringBuilder builder) {
-    Preconditions.checkArgument(isHttpToken(name));
-    builder.append(PARAM_SEPARATOR);
-    builder.append(name);
-  }
-
-  /**
-   * Writes an HTTP parameter value to a given string builder.
-   *
-   * @param value The parameter value, which must satisfy
-   *     {@link #isQuotedStringEncodable}.
-   * @param builder A string builder to write the value to.
-   * @throws IllegalArgumentException if {@code value} can't be encoded.
-   */
-  public static void writeParameterValue(String value, StringBuilder builder) {
-    if (isHttpToken(value)) {
-      builder.append(value);
-    } else {
-      writeQuotedString(value, builder);
-    }
-  }
-
-  /**
-   * Writes a string to a string builder in HTTP quoted-string format.
-   *
-   * @param string The string to be written.
-   * @param builder A string builder to write the string to.
-   * @throws IllegalArgumentException if {@code string} can't be encoded.
-   */
-  public static void writeQuotedString(String string, StringBuilder builder) {
-    Preconditions.checkArgument(isQuotedStringEncodable(string),
-        "String can't be encoded as an HTTP parameter value: %s", string);
-    builder.append(STRING_DELIMITER);
-    for (char c : string.toCharArray()) {
-      if (c == STRING_QUOTE || c == STRING_DELIMITER) {
-        builder.append(STRING_QUOTE);
-      }
-      builder.append(c);
-    }
-    builder.append(STRING_DELIMITER);
-  }
-
-  /**
-   * Parses an HTTP quoted-string.
-   *
-   * @param string The string to parse.
-   * @return The parsed value of the quoted string.
-   * @throws IllegalArgumentException if the string isn't a valid quoted-string.
-   */
-  public static String parseHttpQuotedString(String string) {
-    int end = string.length();
-    checkQuotedStringArgument(
-        (end >= 2
-            && string.charAt(0) == STRING_DELIMITER
-            && string.charAt(end - 1) == STRING_DELIMITER),
-        string);
-    StringBuilder builder = new StringBuilder();
-    boolean pendingQuote = false;
-    for (char c : string.substring(1, end - 1).toCharArray()) {
-      if (pendingQuote) {
-        pendingQuote = false;
-        checkQuotedStringArgument(CHAR.matches(c), string);
-        builder.append(c);
-      } else if (c == STRING_QUOTE) {
-        pendingQuote = true;
-      } else {
-        checkQuotedStringArgument(QDTEXT.matches(c), string);
-        builder.append(c);
-      }
-    }
-    checkQuotedStringArgument(!pendingQuote, string);
-    return builder.toString();
-  }
-
-  /**
-   * Gets the http range header value for requesting the first number of bytes.
-   *
-   * @param bytes The number of bytes to request.
-   * @return The range header value
-   */
-  public static String getRangeString(int bytes) {
-    return String.format(RANGE_FORMAT, bytes);
-  }
-
-  private static void checkQuotedStringArgument(boolean succeed, String argument) {
-    Preconditions.checkArgument(succeed, "Incorrectly formatted quoted-string: %s", argument);
-  }
-
-  // These names are taken directly from RFC 2616.
-
-  private static final CharMatcher OCTET = CharMatcher.inRange('\u0000', '\u00ff');
-
-  // Not strictly correct: CHAR technically includes CR and LF, but only for
-  // line folding.  Since we're looking at a post-line-folding string, they
-  // shouldn't be present.
-  private static final CharMatcher CHAR = difference(CharMatcher.ASCII, CharMatcher.anyOf("\n\r"));
-
-  /** ASCII control characters. */
-  public static final CharMatcher CTLS =
-      CharMatcher.inRange('\u0000', '\u001f').or(CharMatcher.is('\u007f'));
-
-  /** ASCII alphabetic characters. */
-  public static final CharMatcher ALPHA =
-      CharMatcher.anyOf("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
-
-  /** ASCII digit characters. */
-  public static final CharMatcher DIGIT = CharMatcher.anyOf("0123456789");
-
-  /** Linear white space. */
-  public static final CharMatcher LWS = CharMatcher.anyOf(" \t");
-
-  /** Plain text. */
-  public static final CharMatcher TEXT = union(difference(OCTET, CTLS), LWS);
-
-  // Text that can be included in a quoted-string without backquotes.  Note that
-  // RFC 2616 specifies only '"' as an exception, but clearly '\\' needs to be
-  // excepted as well.
-  private static final CharMatcher QDTEXT = difference(TEXT, CharMatcher.anyOf("\"\\"));
-
-  // Separator characters that aren't allowed in most places except inside
-  // quoted-strings.
-  private static final CharMatcher SEPARATORS = CharMatcher.anyOf("()<>@,;:\\\"/[]?={} \t");
-
-  // The constituent characters of a token.
-  private static final CharMatcher TOKEN = difference(CharMatcher.ASCII, union(CTLS, SEPARATORS));
-
-  private static CharMatcher union(CharMatcher m1, CharMatcher m2) {
-    return m1.or(m2);
-  }
-
-  private static CharMatcher difference(CharMatcher m1, CharMatcher m2) {
-    return m1.and(m2.negate());
-  }
-
-  // HTTP date formats (from RFC 2616):
-  //
-  // HTTP-date    = rfc1123-date | rfc850-date | asctime-date
-  // rfc1123-date = wkday "," SP date1 SP time SP "GMT"
-  // rfc850-date  = weekday "," SP date2 SP time SP "GMT"
-  // asctime-date = wkday SP date3 SP time SP 4DIGIT
-  // date1        = 2DIGIT SP month SP 4DIGIT
-  //                ; day month year (e.g., 02 Jun 1982)
-  // date2        = 2DIGIT "-" month "-" 2DIGIT
-  //                ; day-month-year (e.g., 02-Jun-82)
-  // date3        = month SP ( 2DIGIT | ( SP 1DIGIT ))
-  //                ; month day (e.g., Jun  2)
-  // time         = 2DIGIT ":" 2DIGIT ":" 2DIGIT
-  //                ; 00:00:00 - 23:59:59
-  // wkday        = "Mon" | "Tue" | "Wed"
-  //              | "Thu" | "Fri" | "Sat" | "Sun"
-  // weekday      = "Monday" | "Tuesday" | "Wednesday"
-  //              | "Thursday" | "Friday" | "Saturday" | "Sunday"
-  // month        = "Jan" | "Feb" | "Mar" | "Apr"
-  //              | "May" | "Jun" | "Jul" | "Aug"
-  //              | "Sep" | "Oct" | "Nov" | "Dec"
-
-  private static final String DATE_FORMAT_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz";
-  private static final String DATE_FORMAT_RFC850 = "EEEE, dd-MMM-yy HH:mm:ss zzz";
-  private static final String DATE_FORMAT_ASCTIME = "EEE MMM dd HH:mm:ss yyyy";
-
-  /**
-   * Generates an HTTP date string.
-   *
-   * @param date A date value specified as a non-negative difference from the
-   *     epoch in milliseconds.
-   * @return An HTTP date string representing that date.
-   */
-  public static String generateHttpDate(long date) {
-    return getDateFormat(DATE_FORMAT_RFC1123).format(new Date(date));
-  }
-
-  /**
-   * Parses an HTTP date string.
-   *
-   * @param dateString The string to parse.
-   * @return The difference, measured in milliseconds, between the specified
-   *     date and 1970-01-01T00:00:00Z.
-   * @throws IllegalArgumentException if the date string can't be parsed.
-   */
-  public static long parseHttpDate(String dateString) {
-    try {
-      return parseDate(DATE_FORMAT_RFC1123, dateString);
-    } catch (ParseException e) {
-      // Fall through to next format.
-    }
-    try {
-      return parseDate(DATE_FORMAT_RFC850, dateString);
-    } catch (ParseException e) {
-      // Fall through to next format.
-    }
-    try {
-      return parseDate(DATE_FORMAT_ASCTIME, dateString);
-    } catch (ParseException e) {
-      throw new IllegalArgumentException("Can't parse as HTTP date string: " + dateString);
-    }
-  }
-
-  private static long parseDate(String formatString, String dateString)
-      throws ParseException {
-    return getDateFormat(formatString).parse(dateString).getTime();
-  }
-
-  private static DateFormat getDateFormat(String formatString) {
-    DateFormat format = new SimpleDateFormat(formatString);
-    format.setCalendar(Calendar.getInstance(GMT, Locale.US));
-    return format;
-  }
-
-  private static final TimeZone GMT = TimeZone.getTimeZone("GMT");
-
-  /**
-   * Is the given string a valid domain name?  Uses a fairly restrictive
-   * definition, corresponding to the "preferred syntax" of RFC 1034 as updated
-   * by RFC 1123.
-   *
-   * @param string The string to be tested.
-   * @return True only if the string is a valid domain name.
-   */
-  public static boolean isValidDomainName(String string) {
-    return parseDomainName(string) != null;
-  }
-
-  /**
-   * Converts a given domain name to its canonical form.  This should eventually
-   * handle IDNA names, but for now we just canonicalize case.
-   *
-   * @param domainName The domain name to convert.
-   * @return The canonical form for {@code domainName}.
-   * @throws IllegalArgumentException if {@code domainName} doesn't satisfy
-   *     {@code #isValidDomainName}.
-   */
-  public static String canonicalizeDomainName(String domainName) {
-    List<String> labels = parseDomainName(domainName);
-    Preconditions.checkArgument(labels != null, "Not a valid domain name: %s", domainName);
-    return labelsToDomanName(labels);
-  }
-
-  /**
-   * Gets the "parent domain" name of a domain name.
-   *
-   * @param domainName The domain name to get the parent domain name of.
-   * @return The parent domain name, or {@code null} if there isn't one.
-   * @throws IllegalArgumentException if {@code domainName} doesn't satisfy
-   *     {@code #isValidDomainName}.
-   */
-  public static String domainNameParent(String domainName) {
-    List<String> labels = parseDomainName(domainName);
-    Preconditions.checkArgument(labels != null, "Not a valid domain name: %s", domainName);
-    if (labels.size() < 2) {
-      return null;
-    }
-    labels.remove(0);
-    return labelsToDomanName(labels);
-  }
-
-  private static List<String> parseDomainName(String domainName) {
-    if (!(domainName.length() >= 1 && domainName.length() <= 255)) {
-      return null;
-    }
-    List<String> labels = Lists.newArrayList(DOMAIN_NAME_SPLITTER.split(domainName));
-    if (!(labels.size() >= 1 && labels.size() <= 127)) {
-      return null;
-    }
-    for (String label : labels) {
-      if (!isValidDomainLabel(label)) {
-        return null;
-      }
-    }
-    // Eliminates IPv4 addresses:
-    if (DIGIT.matchesAllOf(labels.get(labels.size() - 1))) {
-      return null;
-    }
-    return labels;
-  }
-
-  private static boolean isValidDomainLabel(String label) {
-    return label.length() >= 1
-        && label.length() <= 63
-        && DOMAIN_LABEL_CHAR.matchesAllOf(label)
-        && label.charAt(0) != '-'
-        && label.charAt(label.length() - 1) != '-';
-  }
-
-  private static String labelsToDomanName(List<String> labels) {
-    return DOMAIN_NAME_JOINER.join(
-        Iterables.transform(labels,
-            new Function<String, String>() {
-              @Override
-              public String apply(String label) {
-                return label.toLowerCase(Locale.US);
-              }
-            }));
-  }
-
-  private static final CharMatcher DOMAIN_LABEL_CHAR = ALPHA.or(DIGIT).or(CharMatcher.is('-'));
-  private static final Splitter DOMAIN_NAME_SPLITTER = Splitter.on('.');
-  private static final Joiner DOMAIN_NAME_JOINER = Joiner.on('.');
-}
diff --git a/src/com/google/enterprise/secmgr/common/SecurePasswordHasher.java b/src/com/google/enterprise/secmgr/common/SecurePasswordHasher.java
deleted file mode 100644
index 5621fa6..0000000
--- a/src/com/google/enterprise/secmgr/common/SecurePasswordHasher.java
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.base.Charsets;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Arrays;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.crypto.KeyGenerator;
-import javax.crypto.Mac;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.PBEKeySpec;
-
-/**
- * This class implements two password hashers.  One is based on the
- * PBKDF2 specification using HMAC-SHA256 as the underlying
- * primitive.  PBKDF is short for Password-Based Key Derivation
- * Function.  Requires JCE provider that implements the
- * "PBKDF2WithHmacSHA1" algorithm.  (Briefly, this algorithm and parameter
- * selection provides some protection against certain types of offline
- * password dictionary attacks.)  This algorithm is not deterministic,
- * but it allows the possibility of "verifying" a fingerprint.
- *
- * To generate fingerprints, use SecurePasswordHasher.getFingerprint().
- *
- * The other hasher is a simple MAC.  It is deterministic, but
- * the key is not saved, which means that it is not possible to
- * verify the hash later.  It is the more secure option of the two
- * because an attacker may only try to guess username/passwords by
- * querying the service while it is running.
- *
- * To generate MAC tags, user SecurePasswordHasher.getMac().
- *
- * #################################################################
- * WARNING:
- * This does not safely obfuscate weak passwords.  Only use if it
- * is absolutely necessary to store/log information about passwords,
- * and ensure that files with stored fingerprints have appropriate
- * permissions.
- * #################################################################
- *
- * Please see the RFC for more information on password hashing
- * security: http://tools.ietf.org/html/rfc2898.
- */
-public class SecurePasswordHasher {
-
-  private static final Logger LOGGER =
-      Logger.getLogger(SecurePasswordHasher.class.getName());
-
-  private static final SecureRandom prng = new SecureRandom();
-
-  private static final int kNumSeedBytes = 16;
-  private static final int kNumIterations = 1000;
-  private static final int kNumOutputBits = 128;
-  private static final String kHashAlgorithm = "PBKDF2WithHmacSHA1";
-  private static Mac mac;
-
-  static {
-    // Initialize the MAC key.
-    try {
-      KeyGenerator kg = KeyGenerator.getInstance("HmacSHA1");
-      mac = Mac.getInstance("HmacSHA1");
-      mac.init(kg.generateKey());
-    } catch (NoSuchAlgorithmException e) {
-      LOGGER.log(Level.SEVERE, "Could not initialize MAC", e);
-      mac = null;
-    } catch (InvalidKeyException e) {
-      LOGGER.log(Level.SEVERE, "Could not initialize MAC", e);
-      mac = null;
-    }
-  }
-
-  /**
-   * We don't want this class to be instantiated.
-   */
-  private SecurePasswordHasher() {
-  }
-
-  /**
-   * A container for a fingerprint specification.  From this fingerprint
-   * specification, it should be easy to verify that a given password
-   * generated the fingerprint.  Finding the password from the fingerprint
-   * should be much more difficult as long as the password was "well-chosen".
-   */
-  public static class Fingerprint {
-    private final String hash;
-    private final String seed;
-    private final String algorithm;
-    private final int iterations;
-
-    Fingerprint(String hash, String seed, String algorithm, int iterations) {
-      this.hash = hash;
-      this.seed = seed;
-      this.algorithm = algorithm;
-      this.iterations = iterations;
-    }
-
-    public String hash() {
-      return hash;
-    }
-
-    public String seed() {
-      return seed;
-    }
-
-    public String algorithm() {
-      return algorithm;
-    }
-
-    public int iterations() {
-      return iterations;
-    }
-
-    /**
-     * Parses a Fingerprint object from a string.
-     * @param fingerprint the output of toString() from a
-     * Fingerprint object
-     */
-    public static Fingerprint parseFingerprint(String fingerprint)
-        throws IllegalArgumentException {
-      String[] parts = fingerprint.split(":");
-      if (parts.length != 4) {
-        throw new IllegalArgumentException(
-            "Incorrectly formatted fingerprint: " + fingerprint);
-      }
-
-      int iterations;
-      try {
-        iterations = Integer.parseInt(parts[3]);
-      } catch (NumberFormatException e) {
-        throw new IllegalArgumentException("Could not parse number of " +
-            "iterations from fingerprint: " + fingerprint);
-      }
-
-      return new Fingerprint(parts[0], parts[1], parts[2], iterations);
-    }
-
-    @Override
-    public String toString() {
-      return hash + ":" + seed + ":" + algorithm + ":" + iterations;
-    }
-
-    @Override
-    public int hashCode() {
-      return toString().hashCode();
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (!(obj instanceof Fingerprint)) {
-        return false;
-      }
-      return toString().equals(((Fingerprint) obj).toString());
-    }
-  }
-
-  /**
-   * Produce a fingerprint from an input string.  This is non-deterministic
-   * and will use safe defaults for the parameters (as of 05/2009).
-   */
-  public static synchronized Fingerprint getFingerprint(String input) {
-    byte[] seed = new byte[kNumSeedBytes];
-
-    // Randomly choose a seed.
-    synchronized (prng) {
-      prng.nextBytes(seed);
-    }
-
-    byte[] hash = hashString(input, kHashAlgorithm, kNumIterations, seed);
-    return new Fingerprint(Base64.encode(hash), Base64.encode(seed),
-        kHashAlgorithm, kNumIterations);
-  }
-
-  /**
-   * Returns true iff the input is a valid producer of the given fingerprint.
-   * @param input the candidate input string
-   * @param fingerprint
-   */
-  public static boolean verifyFingerprint(String input, Fingerprint fingerprint) {
-    byte[] seedBytes;
-    try {
-      seedBytes = Base64.decode(fingerprint.seed());
-    } catch (Base64DecoderException e) {
-      LOGGER.warning("Could not base64 decode input string: " + fingerprint.seed());
-      return false;
-    }
-
-    byte[] hashBytes;
-    try {
-      hashBytes = Base64.decode(fingerprint.hash());
-    } catch (Base64DecoderException e) {
-      LOGGER.warning("Could not base64 decode input string: " + fingerprint.hash());
-      return false;
-    }
-    return Arrays.equals(hashBytes, hashString(input, fingerprint.algorithm(),
-        fingerprint.iterations(), seedBytes));
-  }
-
-  /**
-   * Returns the MAC of the combination of the username and password.
-   * The key used to MAC these messages is not saved, so this effectively
-   * erases the threat of doing off-line brute force password-guessing.
-   * If an attacker has access to the logs, they may mount an on-line
-   * attack (querying many different known username/password combos to see
-   * if they match unknown username/password MACs), but this is a much
-   * more constrained environment.
-   *
-   * This function is deterministic, however, which enables debugging by
-   * tracking that a particular username/password is being used in
-   * multiple places or tracking how frequently a user logs in, etc.
-   *
-   * @param username required so an attacker cannot easily tell if
-   * two users have the same password by looking at the logs
-   * @param password password to mac
-   */
-  public static String getMac(String username, String password) {
-    return Base64.encode(macInput(username, password));
-  }
-
-  /**
-   * Run the input string through the PBKDF with the given parameters and
-   * return the result.
-   */
-  private static byte[] hashString(String input, String algorithm,
-                            int iterations, byte[] seed) {
-
-    PBEKeySpec keySpec = new PBEKeySpec(input.toCharArray(), seed,
-                                        iterations, kNumOutputBits);
-
-    SecretKeyFactory factory;
-    try {
-      factory = SecretKeyFactory.getInstance(algorithm);
-    } catch (NoSuchAlgorithmException e) {
-      LOGGER.log(Level.SEVERE, "Could not get key spec", e);
-      return new byte[kNumSeedBytes];  // Don't reveal information about the password.
-    }
-
-    SecretKey hash;
-    try {
-      hash = factory.generateSecret(keySpec);
-    } catch (InvalidKeySpecException e) {
-      LOGGER.severe("Could not load hash algorithm: " + e);
-      return new byte[kNumSeedBytes];  // Don't reveal information about the password.
-    }
-    return hash.getEncoded();
-  }
-
-  /**
-   * Returns a one-way keyed function output for the given username and
-   * password.
-   *
-   * @param username required so an attacker cannot easily tell if two users
-   *     have the same password by looking at the logs
-   * @param password password to mac
-   */
-  public static byte[] macInput(String username, String password) {
-    if (mac == null) {
-      LOGGER.severe("tried to MAC message when mac object uninitialized");
-      return new byte[0];
-    }
-    return mac.doFinal((username + ":" + password).getBytes(Charsets.UTF_8));
-  }
-
-  /**
-   * This provides a simple command-line tool to verify passwords.
-   */
-  public static void main(String[] args) throws Throwable {
-    int numArgs = args.length;
-    if (numArgs < 2 || numArgs > 3) {
-      System.err.println("Usage: SecurePasswordHasher password [fingerprint]");
-      System.exit(1);
-    }
-    if (numArgs == 2) {
-      System.out.println(SecurePasswordHasher.getFingerprint(args[1])
-                         .toString());
-    } else {
-      Fingerprint fingerprint = Fingerprint.parseFingerprint(args[2]);
-      boolean verified =
-          SecurePasswordHasher.verifyFingerprint(args[1], fingerprint);
-      if (verified) {
-        System.out.println("Password is correct");
-      } else {
-        System.out.println("Invalid password");
-      }
-    }
-
-    System.exit(0);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/SecurityManagerUtil.java b/src/com/google/enterprise/secmgr/common/SecurityManagerUtil.java
index 87bd887..395d6d3 100644
--- a/src/com/google/enterprise/secmgr/common/SecurityManagerUtil.java
+++ b/src/com/google/enterprise/secmgr/common/SecurityManagerUtil.java
@@ -15,35 +15,9 @@
 package com.google.enterprise.secmgr.common;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.BoundedExecutorService;
 
-import org.joda.time.DateTimeUtils;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.security.SecureRandom;
-import java.util.Collection;
-import java.util.Formatter;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
 import javax.annotation.concurrent.ThreadSafe;
 
 /**
@@ -59,27 +33,6 @@
   }
 
   /**
-   * Remove all elements specified by a given predicate from a collection.
-   *
-   * @param iterable The collection to modify.
-   * @param predicate The predicate identifying the elements to remove.
-   * @return A collection of the elements that were removed.
-   */
-  public static <T> Collection<T> removeInPlace(Iterable<T> iterable, Predicate<T> predicate) {
-    ImmutableList.Builder<T> builder = ImmutableList.builder();
-    Iterator<T> iterator = iterable.iterator();
-    boolean changed = false;
-    while (iterator.hasNext()) {
-      T element = iterator.next();
-      if (predicate.apply(element)) {
-        iterator.remove();
-        builder.add(element);
-      }
-    }
-    return builder.build();
-  }
-
-  /**
    * Annotate a log message with a given session ID.  This should be implemented
    * in the session manager, but can't be due to cyclic build dependencies.
    *
@@ -92,72 +45,6 @@
   }
 
   /**
-   * Generate a random nonce as a byte array.
-   *
-   * @param nBytes The number of random bytes to generate.
-   * @return A randomly generated byte array of the given length.
-   */
-  public static byte[] generateRandomNonce(int nBytes) {
-    byte[] randomBytes = new byte[nBytes];
-    synchronized (prng) {
-      prng.nextBytes(randomBytes);
-    }
-    return randomBytes;
-  }
-
-  /**
-   * Generate a random nonce as a hexadecimal string.
-   *
-   * @param nBytes The number of random bytes to generate.
-   * @return A randomly generated hexadecimal string.
-   */
-  public static String generateRandomNonceHex(int nBytes) {
-    return bytesToHex(generateRandomNonce(nBytes));
-  }
-
-  private static final SecureRandom prng = new SecureRandom();
-
-  /**
-   * Convert a byte array to a hexadecimal string.
-   *
-   * @param bytes The byte array to convert.
-   * @return The equivalent hexadecimal string.
-   */
-  public static String bytesToHex(byte[] bytes) {
-    Preconditions.checkNotNull(bytes);
-    Formatter f = new Formatter();
-    for (byte b : bytes) {
-      f.format("%02x", b);
-    }
-    return f.toString();
-  }
-
-  /**
-   * Convert a hexadecimal string to a byte array.
-   *
-   * @param hexString The hexadecimal string to convert.
-   * @return The equivalent array of bytes.
-   * @throws IllegalArgumentException if the string isn't valid hexadecimal.
-   */
-  public static byte[] hexToBytes(String hexString) {
-    Preconditions.checkNotNull(hexString);
-    int len = hexString.length();
-    Preconditions.checkArgument(len % 2 == 0);
-    int nBytes = len / 2;
-    byte[] decoded = new byte[nBytes];
-    int j = 0;
-    for (int i = 0; i < nBytes; i += 1) {
-      int d1 = Character.digit(hexString.charAt(j++), 16);
-      int d2 = Character.digit(hexString.charAt(j++), 16);
-      if (d1 < 0 || d2 < 0) {
-        throw new IllegalArgumentException("Non-hexadecimal character in string: " + hexString);
-      }
-      decoded[i] = (byte) ((d1 << 4) + d2);
-    }
-    return decoded;
-  }
-
-  /**
    * Is a given remote "before" time valid?  In other words, is it possible that
    * the remote "before" time is less than or equal to the remote "now" time?
    *
@@ -187,280 +74,4 @@
   }
 
   private static final long CLOCK_SKEW_TIME = 5000;
-
-  /**
-   * Compare two URLs for equality.  Preferable to using the {@link URL#equals}
-   * because the latter calls out to DNS and can block.
-   *
-   * @param url1 A URL to compare.
-   * @param url2 Another URL to compare.
-   * @return True if the two URLs are the same.
-   */
-  public static boolean areUrlsEqual(URL url1, URL url2) {
-    if (url1 == null || url2 == null) {
-      return url1 == null && url2 == null;
-    }
-    return areStringsEqualIgnoreCase(url1.getProtocol(), url2.getProtocol())
-        && areStringsEqualIgnoreCase(url1.getHost(), url2.getHost())
-        && url1.getPort() == url2.getPort()
-        && areStringsEqual(url1.getFile(), url2.getFile())
-        && areStringsEqual(url1.getRef(), url2.getRef());
-  }
-
-  private static boolean areStringsEqual(String s1, String s2) {
-    return s1 == s2 || ((s1 == null) ? s2 == null : s1.equals(s2));
-  }
-
-  private static boolean areStringsEqualIgnoreCase(String s1, String s2) {
-    return s1 == s2 || ((s1 == null) ? s2 == null : s1.equalsIgnoreCase(s2));
-  }
-
-  /**
-   * @return The value of ENT_CONFIG_NAME from the GSA configuration.
-   *   If not running on a GSA (e.g. for testing), return a fixed string.
-   */
-  public static String getGsaEntConfigName() {
-    String entConfigName = System.getProperty("gsa.entityid");
-    if (entConfigName == null) {
-      return "testing";
-    }
-    return entConfigName;
-  }
-
-  /**
-   * @return A URI builder with default scheme and host arguments.
-   */
-  public static UriBuilder uriBuilder() {
-    return new UriBuilder("http", "google.com");
-  }
-
-  /**
-   * @param scheme The URI Scheme to use.
-   * @param host The URI host to use.
-   * @return A URI builder with the given scheme and host.
-   */
-  public static UriBuilder uriBuilder(String scheme, String host) {
-    return new UriBuilder(scheme, host);
-  }
-
-  /**
-   * A class to build URIs by incrementally specifying their path segments.
-   */
-  public static final class UriBuilder {
-    private final String scheme;
-    private final String host;
-    private final StringBuilder pathBuilder;
-
-    private UriBuilder(String scheme, String host) {
-      this.scheme = scheme;
-      this.host = host;
-      pathBuilder = new StringBuilder();
-    }
-
-    /**
-     * Add a segment to the path being accumulated.
-     *
-     * @param segment The segment to add.
-     * @return The builder, for convenience.
-     * @throws IllegalArgumentException if the segment contains any illegal characters.
-     */
-    public UriBuilder addSegment(String segment) {
-      Preconditions.checkArgument(segment != null && !segment.contains("/"),
-          "Path segments may not contain the / character: %s", segment);
-      pathBuilder.append("/").append(segment);
-      return this;
-    }
-
-    /**
-     * Add a hex-encoded random segment to the path being accumulated.
-     *
-     * @param nBytes The number of random bytes in the segment.
-     * @return The builder, for convenience.
-     */
-    public UriBuilder addRandomSegment(int nBytes) {
-      return addSegment(generateRandomNonceHex(nBytes));
-    }
-
-    /**
-     * @return The URI composed of the accumulated parts.
-     * @throws IllegalArgumentException if there's a syntax problem with one of the parts.
-     */
-    public URI build() {
-      try {
-        return new URI(scheme, host, pathBuilder.toString(), null);
-      } catch (URISyntaxException e) {
-        throw new IllegalArgumentException(e);
-      }
-    }
-  }
-
-  private static UriBuilder gsaUriBuilder() {
-    return uriBuilder()
-        .addSegment("enterprise")
-        .addSegment("gsa")
-        .addSegment(getGsaEntConfigName());
-  }
-
-  public static UriBuilder smUriBuilder() {
-    return gsaUriBuilder()
-        .addSegment("security-manager");
-  }
-
-  // TODO(cph): make this configurable (preferably in sec mgr config).
-  private static final int THREAD_POOL_SIZE = 20;
-  private static final ExecutorService THREAD_POOL
-      = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
-
-  // Batches of work that are themselves parallizable use a 2nd pool to
-  // parallelize batches while the 1st pool is used for work within the batches.
-  private static final ExecutorService THREAD_POOL_2
-      = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
-
-  // Timeout difference between THREAD_POOL_1 and THREAD_POOL_2.
-  // Otherwise there is a race between their layered use.
-  // So when batches are submitted they use THREAD_POOL_2 to manage
-  // batches, and THREAD_POOL is given less time to carry out tasks.
-  private static final long THREAD_POOL_DELAY_MILLIS = 20;
-
-  @VisibleForTesting
-  static int getPrimaryThreadPoolSize() {
-    return THREAD_POOL_SIZE;
-  }
-
-  /**
-   * Runs a bunch of tasks in parallel using the default/primary thread pool.
-   *
-   * @param callables The tasks to be run.
-   * @param timeoutMillis The maximum amount of time allowed for processing all
-   *     the tasks.
-   * @param sessionId A session ID to use for logging.
-   * @return An immutable list of the computed values, in no particular order.
-   *     The number of values is normally the same as the number of tasks, but
-   *     if the timeoutMillis is reached or if one or more of the tasks generates an
-   *     exception, there will be fewer values than tasks.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static <T> List<T> runInParallel(
-      @Nonnull Iterable<Callable<T>> callables,
-      @Nonnegative long timeoutMillis,
-      @Nonnull String sessionId) {
-    long endTimeMillis = DateTimeUtils.currentTimeMillis() + timeoutMillis;
-    return runInParallel(THREAD_POOL, callables, endTimeMillis, sessionId);
-  }
-
-  private static long calcRemainingMillis(long endTimeMillis) {
-    return endTimeMillis - DateTimeUtils.currentTimeMillis();
-  }
-
-  @CheckReturnValue
-  @Nonnull
-  public static <T> List<T> runBatchesInParallel(
-      @Nonnull Iterable<KeyedBatchOfCallables<T>> keyedBatches, @Nonnegative long timeoutMillis,
-      @Nonnull String sessionId, int maxThreadsPerBatch) {
-    long endTimeMillis = DateTimeUtils.currentTimeMillis() + timeoutMillis;
-
-    /* Convert each batch of callables (a list of callables) into a single
-      callable that has the batch of callables parallelized inside of it */
-    List<Callable<List<T>>> callsWithParallization = Lists.newArrayList();
-    for (KeyedBatchOfCallables<T> keyedBatch : keyedBatches) {
-      Callable<List<T>> oneCallableBatch = keyedBatch
-          .toSingleParallelizedCallable(endTimeMillis, sessionId, maxThreadsPerBatch);
-      callsWithParallization.add(oneCallableBatch);
-    }
-
-    List<List<T>> answerLists = runInParallel(THREAD_POOL_2, callsWithParallization,
-        endTimeMillis, sessionId);
-    ImmutableList.Builder<T> builder = ImmutableList.builder();
-    for (List<T> answerList : answerLists) {
-      builder.addAll(answerList);
-    }
-    return builder.build();
-  }
-
-  @Nonnull
-  private static <T> List<T> runInParallel(
-      @Nonnull ExecutorService threadPool,
-      @Nonnull Iterable<Callable<T>> callables,
-      @Nonnegative long endTimeMillis,
-      @Nonnull String sessionId) {
-    Preconditions.checkNotNull(threadPool);
-    Preconditions.checkNotNull(callables);
-    Preconditions.checkArgument(endTimeMillis >= 0);
-    Preconditions.checkNotNull(sessionId);
-
-    List<T> results = Lists.newArrayList();
-    try {
-      List<Future<T>> futures = threadPool.invokeAll(Lists.newArrayList(callables),
-         calcRemainingMillis(endTimeMillis), TimeUnit.MILLISECONDS);
-      for (Future<T> f : futures) {
-        try {
-          if (f.isDone() && !f.isCancelled()) {
-            T singleResult = f.get();
-            if (null != singleResult) {
-              results.add(singleResult);
-            }
-          }
-        } catch (ExecutionException e) {
-          LOGGER.log(Level.WARNING,
-              SecurityManagerUtil.sessionLogMessage(sessionId, "Exception in worker thread: "),
-              e);
-        }
-      }
-
-    } catch (InterruptedException e) {
-      // Reset the interrupt, then fall through to the cleanup code below.
-      Thread.currentThread().interrupt();
-    }
-    return results;
-  }
-
-  // Contains bounded executors per key.
-  private static HashMap<String, ExecutorService> boundedServicers
-      = new HashMap<String, ExecutorService>();
-
-  /** Returns a bounded executor service for a given key, unless
-    one doesn't exist already, in which it's constructed with
-    maxThreadsPerBatch parameter.  Note that if a bounded executor
-    service by a given name already exists then it's provided
-    without checking that it uses the same number of maxThreadsPerBatch. */
-  private static ExecutorService getServiceForKey(String key, int maxThreadsPerBatch) {
-    ExecutorService service;
-    synchronized(boundedServicers) {
-      if (!boundedServicers.containsKey(key)) {
-        boundedServicers.put(key, new BoundedExecutorService(maxThreadsPerBatch,
-            /*fair*/ false, THREAD_POOL));
-      }
-      service = boundedServicers.get(key);
-    }
-    return service;
-  }
-
-  /** Converts a list of Callables into a single Callable that
-    parallizes the original list of work. */
-  public static class KeyedBatchOfCallables<T> {
-    private final String key;
-    private final List<Callable<T>> work;
-
-    public KeyedBatchOfCallables(String key, List<Callable<T>> work) {
-      this.key = key;
-      this.work = ImmutableList.copyOf(work);
-    }
-
-    /** Returns callable that when invoked performs all the work
-      callables provided in constructor in parallel.  A BoundedExecutorService
-      is used to limit the resources that the parallization takes. */
-    private Callable<List<T>> toSingleParallelizedCallable(final long endTimeMillis,
-        final String sessionId, int maxThreadsPerBatch) {
-      final ExecutorService limitedExecutor = getServiceForKey(key, maxThreadsPerBatch);
-      Callable<List<T>> singleCallable = new Callable<List<T>>() {
-        @Override
-        public List<T> call() {
-          return runInParallel(limitedExecutor, work,
-              endTimeMillis - THREAD_POOL_DELAY_MILLIS, sessionId);
-        }
-      };
-      return singleCallable;
-    }
-  }
 }
diff --git a/src/com/google/enterprise/secmgr/common/SessionUtil.java b/src/com/google/enterprise/secmgr/common/SessionUtil.java
deleted file mode 100644
index cb2474e..0000000
--- a/src/com/google/enterprise/secmgr/common/SessionUtil.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.common;
-
-import com.google.common.base.Preconditions;
-
-import java.util.regex.Pattern;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * A collection of session utilities.
- */
-public final class SessionUtil {
-  /**
-   * The name of the GSA session ID cookie.
-   */
-  public static final String GSA_SESSION_ID_COOKIE_NAME = "GSA_SESSION_ID";
-
-  /**
-   * A regular expression that matches a valid session ID; basically alphanumeric.
-   */
-  // TODO(cph): might be useful to broaden this pattern to handle base64.
-  private static final Pattern SESSION_ID_REGEXP = Pattern.compile("[0-9A-Za-z]*");
-
-  /**
-   * The smallest acceptable length for a session ID string.
-   */
-  private static final int MIN_ACCEPTABLE_SESSION_ID_LENGTH = 16;
-
-  /**
-   * The largest acceptable length for a session ID string.
-   */
-  private static final int MAX_ACCEPTABLE_SESSION_ID_LENGTH = 100;
-
-  /**
-   * The length of a generated session ID string.
-   */
-  private static final int GENERATED_SESSION_ID_LENGTH = MIN_ACCEPTABLE_SESSION_ID_LENGTH;
-
-  // Don't instantiate.
-  private SessionUtil() {
-    throw new UnsupportedOperationException();
-  }
-
-  /**
-   * Generate a session ID for a new session.
-   */
-  public static String generateId() {
-    return SecurityManagerUtil.generateRandomNonceHex(GENERATED_SESSION_ID_LENGTH / 2);
-  }
-
-  /**
-   * Is the given string a valid session ID?
-   *
-   * @param proposedId The string to test.
-   * @return True only if the string is valid.
-   */
-  public static boolean isValidId(String proposedId) {
-    return proposedId != null
-        && proposedId.length() >= MIN_ACCEPTABLE_SESSION_ID_LENGTH
-        && proposedId.length() <= MAX_ACCEPTABLE_SESSION_ID_LENGTH
-        && SESSION_ID_REGEXP.matcher(proposedId).matches();
-  }
-
-  /**
-   * Get the GSA session ID by examining the cookies in an incoming request.
-   *
-   * @param request The HTTP request to check the cookies of.
-   * @return The GSA session ID, if a valid one is found; otherwise null.
-   */
-  public static String findGsaSessionId(HttpServletRequest request) {
-    Preconditions.checkNotNull(request);
-    CookieStore cookies = GCookie.parseHttpRequestCookies(request, null);
-    for (GCookie c : cookies) {
-      if (GSA_SESSION_ID_COOKIE_NAME.equalsIgnoreCase(c.getName())
-          && isValidId(c.getValue())) {
-        return c.getValue();
-      }
-    }
-    return null;
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/common/XmlUtil.java b/src/com/google/enterprise/secmgr/common/XmlUtil.java
index 399c85d..365f447 100644
--- a/src/com/google/enterprise/secmgr/common/XmlUtil.java
+++ b/src/com/google/enterprise/secmgr/common/XmlUtil.java
@@ -14,34 +14,20 @@
 
 package com.google.enterprise.secmgr.common;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-import org.w3c.dom.Attr;
-import org.w3c.dom.Comment;
 import org.w3c.dom.DOMConfiguration;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
 import org.w3c.dom.DocumentType;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.w3c.dom.Text;
 import org.w3c.dom.bootstrap.DOMImplementationRegistry;
 import org.w3c.dom.ls.DOMImplementationLS;
 import org.w3c.dom.ls.LSException;
-import org.w3c.dom.ls.LSInput;
 import org.w3c.dom.ls.LSOutput;
-import org.w3c.dom.ls.LSParser;
 import org.w3c.dom.ls.LSSerializer;
 
 import java.io.IOException;
-import java.io.Reader;
 import java.io.StringWriter;
 import java.io.Writer;
-import java.util.List;
 
-import javax.xml.XMLConstants;
 import javax.xml.namespace.QName;
 
 /**
@@ -157,25 +143,6 @@
   }
 
   /**
-   * Read an XML document from a file.
-   *
-   * @param input The stream to read the document from.
-   * @return The XML document.
-   * @throws IOException if the document can't be parsed.
-   */
-  public Document readXmlDocument(Reader input)
-      throws IOException {
-    LSInput lsInput = domImplLs.createLSInput();
-    lsInput.setCharacterStream(input);
-    LSParser parser = domImplLs.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
-    try {
-      return parser.parse(lsInput);
-    } catch (LSException e) {
-      throw new IOException(e);
-    }
-  }
-
-  /**
    * Write an XML document to a writer.
    *
    * @param document The XML document to write.
@@ -246,338 +213,4 @@
     writeXmlDocument(document, output);
     return output.toString();
   }
-
-  /**
-   * Add a namespace declaration to the given element.
-   *
-   * @param element The element to add the declaration to.
-   * @param prefix The namespace prefix to declare.
-   * @param uri The namespace URI to associate with the given prefix.
-   * @return The namespace declaration as an attribute object.
-   */
-  public static Attr addNamespaceDeclaration(Element element, String prefix, String uri) {
-    return makeAttrChild(
-        element,
-        new QName(
-            XMLConstants.XMLNS_ATTRIBUTE_NS_URI,
-            prefix,
-            XMLConstants.XMLNS_ATTRIBUTE),
-        uri);
-  }
-
-  /**
-   * Get the child elements.
-   *
-   * @param parent The parent element to look in.
-   * @return A list of the child elements.
-   */
-  public static List<Element> getChildElements(Element parent) {
-    List<Element> elements = Lists.newArrayList();
-    NodeList nodes = parent.getChildNodes();
-    for (int i = 0; i < nodes.getLength(); i++) {
-      Node node = nodes.item(i);
-      if (node instanceof Element) {
-        elements.add((Element) node);
-      }
-    }
-    return elements;
-  }
-
-  /**
-   * Find a child element with a given name.
-   *
-   * @param parent The parent element to look in.
-   * @param qname The qname of the child element to look for.
-   * @param required True if the method should throw an exception when no such child.
-   * @return The specified child element, or null if non such (and required is false).
-   * @throws IllegalArgumentException if required is true and there's no such child.
-   */
-  public static Element findChildElement(Element parent, QName qname, boolean required) {
-    NodeList nodes = parent.getChildNodes();
-    for (int i = 0; i < nodes.getLength(); i++) {
-      Node node = nodes.item(i);
-      if (isElementWithQname(node, qname)) {
-        return (Element) node;
-      }
-    }
-    if (required) {
-      throw new IllegalArgumentException(
-          "Entity doesn't contain child named " + qname.toString());
-    }
-    return null;
-  }
-
-  /**
-   * Get the child elements with a given name.
-   *
-   * @param parent The parent element to look in.
-   * @param qname The qname of the child elements to retrieve.
-   * @return A list of the child elements with the given tag name.
-   */
-  public static List<Element> getChildElements(Element parent, QName qname) {
-    List<Element> elements = Lists.newArrayList();
-    NodeList nodes = parent.getChildNodes();
-    for (int i = 0; i < nodes.getLength(); i++) {
-      Node node = nodes.item(i);
-      if (isElementWithQname(node, qname)) {
-        elements.add((Element) node);
-      }
-    }
-    return elements;
-  }
-
-  /**
-   * Count the child elements with a given name.
-   *
-   * @param parent The parent element to look in.
-   * @param qname The qname of the child elements to look for.
-   * @return The number of child elements with the given tag name.
-   */
-  public static int countChildElements(Element parent, QName qname) {
-    int nElements = 0;
-    NodeList nodes = parent.getChildNodes();
-    for (int i = 0; i < nodes.getLength(); i++) {
-      Node node = nodes.item(i);
-      if (isElementWithQname(node, qname)) {
-        nElements += 1;
-      }
-    }
-    return nElements;
-  }
-
-  public static boolean isElementWithQname(Node node, QName qname) {
-    return node instanceof Element && elementHasQname((Element) node, qname);
-  }
-
-  /**
-   * Compare an element's tag name to a given name.
-   *
-   * @param element The element to get the tag name from.
-   * @param qname The qname to compare to.
-   * @return True if the element's tag name and namespace URI match those of the qname.
-   */
-  public static boolean elementHasQname(Element element, QName qname) {
-    return qname.getLocalPart().equals(element.getLocalName())
-        && qname.getNamespaceURI().equals(getNamespaceUri(element));
-  }
-
-  /**
-   * Get the namespace URI of a given element.
-   *
-   * @param element The element to get the namespace URI of.
-   * @return The namespace URI, or the null namespace URI if the element has none.
-   */
-  public static String getNamespaceUri(Element element) {
-    String namespace = element.getNamespaceURI();
-    return (namespace != null) ? namespace : XMLConstants.NULL_NS_URI;
-  }
-
-  /**
-   * Get the text from an element that contains only text.
-   *
-   * @param element The element to get the text from.
-   * @return The text contained in that element.
-   * @throws IllegalArgumentException if the element isn't text-only.
-   */
-  public static String getElementText(Element element) {
-    NodeList nodes = element.getChildNodes();
-    Preconditions.checkArgument(nodes.getLength() == 1
-        && nodes.item(0).getNodeType() == Node.TEXT_NODE);
-    return nodes.item(0).getNodeValue();
-  }
-
-  /**
-   * Get the text from a child element that contains only text.
-   *
-   * @param parent The parent element to look in.
-   * @param qname The qname of the child element to look for.
-   * @param required True if the method should throw an exception when no such child.
-   * @return The text of the specified child element, or null if non such (and required is false).
-   * @throws IllegalArgumentException if required is true and there's no such child.
-   */
-  public static String getChildElementText(Element parent, QName qname, boolean required) {
-    Element child = findChildElement(parent, qname, required);
-    return (child != null) ? getElementText(child) : null;
-  }
-
-  /**
-   * Find all the comments in a given element that contain some given text.
-   *
-   * @param parent The parent element to look in.
-   * @param text The comment string to search for.
-   * @return A list of the comments containing that string.
-   */
-  public static List<Comment> findChildComments(Element parent, String text) {
-    List<Comment> comments = Lists.newArrayList();
-    NodeList nodes = parent.getChildNodes();
-    for (int index = 0; index < nodes.getLength(); index++) {
-      Node node = nodes.item(index);
-      if (node instanceof Comment && node.getNodeValue().contains(text)) {
-        comments.add((Comment) node);
-      }
-    }
-    return comments;
-  }
-
-  /**
-   * Get the descendant elements with a given name.
-   *
-   * @param parent The parent element to look in.
-   * @param qname The qname of the descendant elements to look for.
-   * @return A list of the descendant elements with the given tag name.
-   */
-  public static NodeList getElementsByQname(Element parent, QName qname) {
-    return parent.getElementsByTagNameNS(qname.getNamespaceURI(), qname.getLocalPart());
-  }
-
-  /**
-   * Get a given element's attribute with a given name.
-   *
-   * @param element The element to get the attribute from.
-   * @param qname The qname of the attribute to look for.
-   * @param required True if the method should throw an exception when no such attribute.
-   * @return The attribute's value, or null if no such attribute (and required is false).
-   * @throws IllegalArgumentException if no such attribute and required is true.
-   */
-  public static String findAttribute(Element element, QName qname, boolean required) {
-    String ns = qname.getNamespaceURI();
-    String localName = qname.getLocalPart();
-    if (ns.isEmpty()) {
-      ns = null;
-    }
-    if (element.hasAttributeNS(ns, localName)) {
-      String value = element.getAttributeNS(ns, localName);
-      return value;
-    }
-    if (required) {
-      throw new IllegalArgumentException(
-          "Entity doesn't contain attribute named " + qname.toString());
-    }
-    return null;
-  }
-
-  /**
-   * Make a new DOM element child.
-   *
-   * @param parent The element to put the new child element in.
-   * @param qname The qname of the new child element.
-   * @return The new child element.
-   */
-  public static Element makeElementChild(Element parent, QName qname) {
-    Element child = makeElement(parent, qname);
-    parent.appendChild(child);
-    return child;
-  }
-
-  /**
-   * Make a new DOM text child.
-   *
-   * @param parent The element to put the new child text in.
-   * @param content The text content of the new child.
-   * @return The new child text.
-   */
-  public static Text makeTextChild(Element parent, String content) {
-    Text child = makeText(parent, content);
-    parent.appendChild(child);
-    return child;
-  }
-
-  /**
-   * Make a new DOM element child containing some text.
-   *
-   * @param parent The element to put the new child element in.
-   * @param qname The name of the new child element.
-   * @param content The text content of the new child element.
-   * @return The new child element.
-   */
-  public static Element makeTextElementChild(Element parent, QName qname, String content) {
-    Element child = makeElementChild(parent, qname);
-    makeTextChild(child, content);
-    return child;
-  }
-
-  /**
-   * Make a new DOM comment child.
-   *
-   * @param parent The element to put the new child comment in.
-   * @param content The text content of the new child comment.
-   * @return The new child comment.
-   */
-  public static Comment makeCommentChild(Element parent, String content) {
-    Comment child = makeComment(parent, content);
-    parent.appendChild(child);
-    return child;
-  }
-
-  /**
-   * Make a new DOM attribute child.
-   *
-   * @param parent The element to put the new child attribute in.
-   * @param qname The qname of the new child attribute.
-   * @param value The value of the new child attribute.
-   * @return The new child attribute.
-   */
-  public static Attr makeAttrChild(Element parent, QName qname, String value) {
-    Attr child = makeAttr(parent, qname, value);
-    parent.setAttributeNodeNS(child);
-    return (child);
-  }
-
-  /**
-   * Make a new DOM element.
-   *
-   * @param element Any element in the target document for the new element.
-   * @param qname The qname of the new element.
-   * @return The new element.
-   */
-  public static Element makeElement(Element element, QName qname) {
-    return element.getOwnerDocument()
-        .createElementNS(qname.getNamespaceURI(), qnameToString(qname));
-  }
-
-  /**
-   * Make a new DOM text.
-   *
-   * @param element Any element in the target document for the new text.
-   * @param content The content of the new text.
-   * @return The new text.
-   */
-  public static Text makeText(Element element, String content) {
-    return element.getOwnerDocument().createTextNode(content);
-  }
-
-  /**
-   * Make a new DOM comment.
-   *
-   * @param element Any element in the target document for the new comment.
-   * @param content The content of the new comment.
-   * @return The new comment.
-   */
-  public static Comment makeComment(Element element, String content) {
-    return element.getOwnerDocument().createComment(content);
-  }
-
-  /**
-   * Make a new DOM attribute.
-   *
-   * @param element Any element in the target document for the new attribute.
-   * @param qname The qname of the new attribute.
-   * @param value The attribute's value.
-   * @return The new attribute.
-   */
-  public static Attr makeAttr(Element element, QName qname, String value) {
-    Attr attr = element.getOwnerDocument()
-        .createAttributeNS(qname.getNamespaceURI(), qnameToString(qname));
-    attr.setValue(value);
-    return attr;
-  }
-
-  private static String qnameToString(QName qname) {
-    String localPart = qname.getLocalPart();
-    String prefix = qname.getPrefix();
-    return
-        (XMLConstants.DEFAULT_NS_PREFIX.equals(prefix))
-        ? localPart
-        : prefix + ":" + localPart;
-  }
 }
diff --git a/src/com/google/enterprise/secmgr/config/AuthnAuthority.java b/src/com/google/enterprise/secmgr/config/AuthnAuthority.java
deleted file mode 100644
index 64599aa..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnAuthority.java
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Maps;
-import com.google.enterprise.secmgr.common.SecurityManagerUtil;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-import java.lang.reflect.Type;
-import java.net.URI;
-import java.util.Map;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An authentication authority describes an authority that validates credentials.
- */
-@ThreadSafe
-@ParametersAreNonnullByDefault
-public class AuthnAuthority {
-  @GuardedBy("itself")
-  @Nonnull static final Map<URI, AuthnAuthority> AUTHORITIES = Maps.newHashMap();
-
-  @Nonnull private final URI uri;
-
-  private AuthnAuthority(URI uri) {
-    this.uri = uri;
-  }
-
-  /**
-   * Makes an authority.
-   *
-   * @param uri The URI for this authority.
-   * @return The unique authority with that URI, creating it if necessary.
-   * @throws IllegalArgumentException if the URI is invalid.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static AuthnAuthority make(URI uri) {
-    checkUri(uri);
-    AuthnAuthority authority;
-    synchronized (AUTHORITIES) {
-      authority = AUTHORITIES.get(uri);
-      if (authority == null) {
-        authority = new AuthnAuthority(uri);
-        AUTHORITIES.put(uri, authority);
-      }
-    }
-    return authority;
-  }
-
-  private static void checkUri(URI uri) {
-    Preconditions.checkNotNull(uri);
-    Preconditions.checkArgument(uri.isAbsolute());
-    Preconditions.checkArgument(!uri.isOpaque());
-    Preconditions.checkArgument(uri.getQuery() == null);
-    Preconditions.checkArgument(uri.getFragment() == null);
-  }
-
-  static AuthnAuthority make(String configName) {
-    return make(SecurityManagerUtil.smUriBuilder().addSegment(configName).build());
-  }
-
-  @VisibleForTesting
-  public static AuthnAuthority make() {
-    return make(SecurityManagerUtil.smUriBuilder().addRandomSegment(16).build());
-  }
-
-  /**
-   * Gets a globally-unique URI for this authority.
-   *
-   * @return The authority's URI.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public URI getUri() {
-    return uri;
-  }
-
-  /**
-   * Gets a globally-unique name for this authority.  Equivalent to
-   * {@code getUri().toString()}.
-   *
-   * @return The authority's name.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public String getName() {
-    return uri.toString();
-  }
-
-  /**
-   * Gets an authority given its URI.
-   *
-   * @param uri The URI of the authority to find.
-   * @return The corresponding authority, or {@code null} if no authority has that URI.
-   */
-  @CheckReturnValue
-  @Nullable
-  public static AuthnAuthority lookupByUri(URI uri) {
-    checkUri(uri);
-    synchronized (AUTHORITIES) {
-      return AUTHORITIES.get(uri);
-    }
-  }
-
-  /**
-   * Gets an authority given its name.
-   *
-   * @param name The name of the authority to find.
-   * @return The corresponding authority, or {@code null} if no authority has that name.
-   */
-  @CheckReturnValue
-  @Nullable
-  public static AuthnAuthority lookupByName(String name) {
-    return lookupByUri(URI.create(name));
-  }
-
-  /**
-   * Gets an authority given its name.
-   *
-   * @param name The name of the authority to find.
-   * @return The corresponding authority.
-   * @throw IllegalArgumentException if no such authority.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static AuthnAuthority getByName(String name) {
-    AuthnAuthority authority = lookupByName(name);
-    if (authority == null) {
-      throw new IllegalArgumentException("No authority of this name: " + name);
-    }
-    return authority;
-  }
-
-  @VisibleForTesting
-  public static void clearAuthorities() {
-    synchronized (AUTHORITIES) {
-      AUTHORITIES.clear();
-    }
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnAuthority)) { return false; }
-    AuthnAuthority other = (AuthnAuthority) object;
-    return getUri().equals(other.getUri());
-  }
-
-  @Override
-  public int hashCode() {
-    return getUri().hashCode();
-  }
-
-  @Override
-  public String toString() {
-    return getName();
-  }
-
-  /**
-   * Gets a predicate that is true for an authority with a given URI.
-   *
-   * @param uri The authority URI to test for.
-   * @return The predicate corresponding to the name.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<AuthnAuthority> getUriPredicate(final URI uri) {
-    return new Predicate<AuthnAuthority>() {
-      public boolean apply(AuthnAuthority authority) {
-        return uri.equals(authority.getUri());
-      }
-    };
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnAuthority.class, new LocalTypeAdapter());
-  }
-
-  private static final class LocalTypeAdapter
-      implements JsonSerializer<AuthnAuthority>, JsonDeserializer<AuthnAuthority> {
-    LocalTypeAdapter() {
-    }
-
-    @Override
-    public JsonElement serialize(AuthnAuthority value, Type type,
-        JsonSerializationContext context) {
-      return context.serialize(value.getName(), String.class);
-    }
-
-    @Override
-    public AuthnAuthority deserialize(JsonElement elt, Type type,
-        JsonDeserializationContext context) {
-      String string = context.deserialize(elt, String.class);
-      return make(URI.create(string));
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechBasic.java b/src/com/google/enterprise/secmgr/config/AuthnMechBasic.java
deleted file mode 100644
index 462b8cb..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechBasic.java
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of an HTTP Basic authentication mechanism.
- */
-@Immutable
-public final class AuthnMechBasic extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "Basic";
-  private static final long DEFAULT_TRUST_DURATION = 20 * 60 * 1000;  // 20 mins
-
-  private final String sampleUrl;
-  private final long trustDuration;
-
-  /**
-   * Make a new HTTP Basic mechanism.
-   *
-   * @param sampleUrl A sample URL that requires HTTP Basic authentication.
-   * @param trustDuration The number of milliseconds for which successfully
-   *     verified credentials are trusted.  This must be a non-negative number.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechBasic make(String name, String sampleUrl, long trustDuration) {
-    return new AuthnMechBasic(name, sampleUrl, trustDuration);
-  }
-
-  /**
-   * Make a new HTTP Basic mechanism with a default trust duration.
-   *
-   * @param sampleUrl A sample URL that requires HTTP Basic authentication.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechBasic make(String name, String sampleUrl) {
-    return make(name, sampleUrl, getDefaultTrustDuration());
-  }
-
-  private AuthnMechBasic(String name, String sampleUrl, long trustDuration) {
-    super(name);
-    this.sampleUrl = checkString(sampleUrl);
-    this.trustDuration = checkTrustDuration(trustDuration);
-  }
-
-  /**
-   * Make a new unconfigured HTTP Basic mechanism.
-   */
-  public static AuthnMechBasic makeEmpty() {
-    return new AuthnMechBasic();
-  }
-
-  private AuthnMechBasic() {
-    super();
-    this.sampleUrl = null;
-    this.trustDuration = getDefaultTrustDuration();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  /**
-   * Get the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        CredentialTransform.make(
-            CredentialTypeSet.PRINCIPAL_AND_PASSWORD,
-            CredentialTypeSet.VERIFIED_PRINCIPAL_AND_PASSWORD));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getSampleUrl(), getTrustDuration());
-  }
-
-  @Override
-  public String getSampleUrl() {
-    return sampleUrl;
-  }
-
-  @Override
-  public long getTrustDuration() {
-    return trustDuration;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechBasic)) { return false; }
-    AuthnMechBasic mech = (AuthnMechBasic) object;
-    return super.equals(mech)
-        && Objects.equal(getSampleUrl(), mech.getSampleUrl())
-        && Objects.equal(getTrustDuration(), mech.getTrustDuration());
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(getSampleUrl(), getTrustDuration());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechBasic.class,
-        ProxyTypeAdapter.make(AuthnMechBasic.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechBasic> {
-    String sampleUrl;
-    long trustDuration = DEFAULT_TRUST_DURATION;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechBasic mechanism) {
-      super(mechanism);
-      sampleUrl = mechanism.getSampleUrl();
-      trustDuration = mechanism.getTrustDuration();
-    }
-
-    @Override
-    public AuthnMechBasic build() {
-      return make(name, sampleUrl, trustDuration);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechClient.java b/src/com/google/enterprise/secmgr/config/AuthnMechClient.java
deleted file mode 100644
index 3dd7c29..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechClient.java
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of a client certificate authentication mechanism.
- */
-@Immutable
-public final class AuthnMechClient extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "X509Client";
-  private static final long DEFAULT_TRUST_DURATION = 20 * 60 * 1000;  // 20 mins
-
-  /**
-   * Make a new ClientAuth mechanism.
-   */
-  public static AuthnMechClient make(String name) {
-    return new AuthnMechClient(name);
-  }
-
-  private AuthnMechClient(String name) {
-    super(name);
-  }
-
-  /**
-   * Make a new unconfigured ClientAuth mechanism.
-   */
-  public static AuthnMechClient makeEmpty() {
-    return new AuthnMechClient();
-  }
-
-  private AuthnMechClient() {
-    super();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  /**
-   * Get the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        CredentialTransform.make(CredentialTypeSet.NONE, CredentialTypeSet.VERIFIED_PRINCIPAL));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name);
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    return (object instanceof AuthnMechClient);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(TYPE_NAME);
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechClient.class,
-        ProxyTypeAdapter.make(AuthnMechClient.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechClient> {
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechClient mechanism) {
-      super(mechanism);
-    }
-
-    @Override
-    public AuthnMechClient build() {
-      return make(name);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechConnector.java b/src/com/google/enterprise/secmgr/config/AuthnMechConnector.java
deleted file mode 100644
index eb87fe2..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechConnector.java
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of a connector authentication mechanism.
- */
-@Immutable
-public final class AuthnMechConnector extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "Connector";
-  private static final long DEFAULT_TRUST_DURATION = 20 * 60 * 1000;  // 20 mins
-
-  private final String connectorName;
-  private final boolean doGroupLookupOnly;
-  private final long trustDuration;
-
-  /**
-   * Makes a new connector mechanism.
-   *
-   * @param name The name for the new mechanism.
-   * @param connectorName The name of the connector to use.
-   * @param doGroupLookupOnly To do only groups lookup and not authentication.
-   * @param trustDuration The number of milliseconds for which successfully
-   *     verified credentials are trusted.  This must be a non-negative number.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechConnector make(String name, String connectorName,
-      boolean doGroupLookupOnly, long trustDuration) {
-    return new AuthnMechConnector(name, connectorName, doGroupLookupOnly, trustDuration);
-  }
-
-  /**
-   * Makes a new connector mechanism with a default trust duration.
-   *
-   * @param name The name for the new mechanism.
-   * @param connectorName The name of the connector to use.
-   * @param doGroupLookupOnly To do only groups lookup and not authentication.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechConnector make(String name, String connectorName,
-      boolean doGroupLookupOnly) {
-    return make(name, connectorName, doGroupLookupOnly, getDefaultTrustDuration());
-  }
-
-  private AuthnMechConnector(String name, String connectorName, boolean doGroupLookupOnly,
-      long trustDuration) {
-    super(name);
-    this.connectorName = checkString(connectorName);
-    this.doGroupLookupOnly = doGroupLookupOnly;
-    this.trustDuration = checkTrustDuration(trustDuration);
-  }
-
-  /**
-   * Makes a new unconfigured connector mechanism.
-   */
-  public static AuthnMechConnector makeEmpty() {
-    return new AuthnMechConnector();
-  }
-
-  private AuthnMechConnector() {
-    super();
-    this.connectorName = null;
-    this.doGroupLookupOnly = false;
-    this.trustDuration = getDefaultTrustDuration();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  /**
-   * Does this connector implement group lookup but not verification?
-   *
-   * @return True only if so.
-   */
-  public boolean doGroupLookupOnly() {
-    return doGroupLookupOnly;
-  }
-
-  /**
-   * Gets the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        doGroupLookupOnly()
-        ? CredentialTransform.make(
-            CredentialTypeSet.VERIFIED_PRINCIPAL,
-            CredentialTypeSet.VERIFIED_GROUPS)
-        : CredentialTransform.make(
-            CredentialTypeSet.PRINCIPAL_AND_PASSWORD,
-            CredentialTypeSet.VERIFIED_PRINCIPAL_PASSWORD_AND_GROUPS));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getConnectorName(), doGroupLookupOnly(), getTrustDuration());
-  }
-
-  @Override
-  public long getTrustDuration() {
-    return trustDuration;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechConnector)) { return false; }
-    AuthnMechConnector mech = (AuthnMechConnector) object;
-    return super.equals(mech)
-        && Objects.equal(getConnectorName(), mech.getConnectorName())
-        && Objects.equal(getTrustDuration(), mech.getTrustDuration());
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(getConnectorName(), getTrustDuration());
-  }
-
-  /**
-   * Gets the name of this connector.
-   *
-   * @return The connector name, never null or empty.
-   */
-  public String getConnectorName() {
-    return connectorName;
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechConnector.class,
-        ProxyTypeAdapter.make(AuthnMechConnector.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechConnector> {
-    String connectorName;
-    boolean doGroupLookupOnly;
-    long trustDuration = DEFAULT_TRUST_DURATION;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechConnector mechanism) {
-      super(mechanism);
-      connectorName = mechanism.getConnectorName();
-      doGroupLookupOnly = mechanism.doGroupLookupOnly();
-      trustDuration = mechanism.getTrustDuration();
-    }
-
-    @Override
-    public AuthnMechConnector build() {
-      return make(name, connectorName, doGroupLookupOnly, trustDuration);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechForm.java b/src/com/google/enterprise/secmgr/config/AuthnMechForm.java
deleted file mode 100644
index 7244b94..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechForm.java
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of a form SSO authentication mechanism.
- */
-@Immutable
-public final class AuthnMechForm extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "CookieBased";
-  private static final long DEFAULT_TRUST_DURATION = 5 * 60 * 1000;  // 5 minutes
-
-  private final String sampleUrl;
-  private final long trustDuration;
-
-  private AuthnMechForm(String name, String sampleUrl, long trustDuration) {
-    super(name);
-    this.sampleUrl = checkStringOrNull(sampleUrl);
-    this.trustDuration = checkTrustDuration(trustDuration);
-  }
-
-  /**
-   * Makes a new HTTP form mechanism.
-   *
-   * @param name A name for the new mechanism.
-   * @param sampleUrl A sample URL that is protected by form authentication.
-   * @param trustDuration The number of milliseconds that successfully
-   *     verified credentials are trusted.  This must be a non-negative number.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechForm make(String name, String sampleUrl, long trustDuration) {
-    return new AuthnMechForm(name, sampleUrl, trustDuration);
-  }
-
-  /**
-   * Makes a new HTTP form mechanism with a default trust duration.
-   *
-   * @param name A name for the new mechanism.
-   * @param sampleUrl A sample URL that is protected by form authentication.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechForm make(String name, String sampleUrl) {
-    return make(name, sampleUrl, getDefaultTrustDuration());
-  }
-
-  /**
-   * Make a new unconfigured HTTP form mechanism.
-   */
-  public static AuthnMechForm makeEmpty() {
-    return new AuthnMechForm();
-  }
-
-  private AuthnMechForm() {
-    super();
-    this.sampleUrl = null;
-    this.trustDuration = getDefaultTrustDuration();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  /**
-   * Get the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        CredentialTransform.make(
-            CredentialTypeSet.PRINCIPAL_AND_PASSWORD,
-            CredentialTypeSet.VERIFIED_PRINCIPAL_AND_PASSWORD),
-        CredentialTransform.make(CredentialTypeSet.COOKIES, CredentialTypeSet.VERIFIED_PRINCIPAL),
-        CredentialTransform.make(CredentialTypeSet.COOKIES, CredentialTypeSet.VERIFIED_ALIASES),
-        CredentialTransform.make(CredentialTypeSet.COOKIES, CredentialTypeSet.VERIFIED_GROUPS));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getSampleUrl(), getTrustDuration());
-  }
-
-  @Override
-  public String getSampleUrl() {
-    return sampleUrl;
-  }
-
-  @Override
-  public long getTrustDuration() {
-    return trustDuration;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechForm)) { return false; }
-    AuthnMechForm mech = (AuthnMechForm) object;
-    return super.equals(mech)
-        && Objects.equal(getSampleUrl(), mech.getSampleUrl())
-        && Objects.equal(getTrustDuration(), mech.getTrustDuration());
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(getSampleUrl(), getTrustDuration());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechForm.class,
-        ProxyTypeAdapter.make(AuthnMechForm.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechForm> {
-    String sampleUrl;
-    long trustDuration = DEFAULT_TRUST_DURATION;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechForm mechanism) {
-      super(mechanism);
-      sampleUrl = mechanism.getSampleUrl();
-      trustDuration = mechanism.getTrustDuration();
-    }
-
-    @Override
-    public AuthnMechForm build() {
-      return make(name, sampleUrl, trustDuration);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechKerberos.java b/src/com/google/enterprise/secmgr/config/AuthnMechKerberos.java
deleted file mode 100644
index 16e7f0f..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechKerberos.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of a kerberos authentication mechanism.
- */
-@Immutable
-public final class AuthnMechKerberos extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "Kerberos";
-  private static final long DEFAULT_TRUST_DURATION = 5 * 60 * 1000;  // 5 minutes
-
-  /**
-   * Make a new Kerberos mechanism.
-   */
-  public static AuthnMechKerberos make(String name) {
-    return new AuthnMechKerberos(name);
-  }
-
-  private AuthnMechKerberos(String name) {
-    super(name);
-  }
-
-  /**
-   * Make a new unconfigured Kerberos mechanism.
-   */
-  public static AuthnMechKerberos makeEmpty() {
-    return new AuthnMechKerberos();
-  }
-
-  private AuthnMechKerberos() {
-    super();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  /**
-   * TODO(jiajia): do we need to place the kerb ticket expiration time here?
-   */
-  @Override
-  public long getTrustDuration() {
-    return getDefaultTrustDuration();
-  }
-
-  /**
-   * Get the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        CredentialTransform.make(CredentialTypeSet.NONE, CredentialTypeSet.VERIFIED_PRINCIPAL));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name);
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    return (object instanceof AuthnMechKerberos);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(TYPE_NAME);
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechKerberos.class,
-        ProxyTypeAdapter.make(AuthnMechKerberos.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechKerberos> {
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechKerberos mechanism) {
-      super(mechanism);
-    }
-
-    @Override
-    public AuthnMechKerberos build() {
-      return make(name);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechLdap.java b/src/com/google/enterprise/secmgr/config/AuthnMechLdap.java
deleted file mode 100644
index 3b2a781..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechLdap.java
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-/**
- * LDAP configuration.
- */
-public final class AuthnMechLdap extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "LDAP";
-  private static final long DEFAULT_TRUST_DURATION = 20 * 60 * 1000;  // 20 mins
-
-  private final boolean enableAuthn;
-  private final boolean enableGroupLookup;
-
-  private final String hostport;
-  private final String bindDn;
-  private final String password;
-  private final String searchBase;
-  private final String userSearchFilter;
-  private final String groupSearchFilter;
-  private final int sslSupport;
-  private final int supportedAuthMethods;
-
-  private final long trustDuration;
-
-  /**
-   * Make a new LDAP AuthN mechanism.
-   *
-   * @param hostport a hostname and port of the format "HOST:PORT"
-   * @param bindDn the DN to bind with, or empty for anonymous binding
-   * @param password the password to bind with, or empty for anonymous binding
-   * @param searchBase component of DN common to all users
-   * @param userSearchFilter filter used to search for user
-   * @param groupSearchFilter filter used to find user's groups
-   * @param sslSupport the type of SSL to use
-   * @param supportedAuthMethods the auth methods supported by the server
-   * @param enableAuthn whether this mech is enabled for authentication
-   * @param enableGroupLookup whether this mech is enabled for doing groups lookup
-   * @param trustDuration The number of milliseconds for which successfully
-   *     verified credentials are trusted.  This must be a non-negative number.
-   * @return A new mechanism with the given configuration
-   */
-  public static AuthnMechLdap make(String name, String hostport, String bindDn,
-                                   String password, String searchBase,
-                                   String userSearchFilter, String groupSearchFilter,
-                                   int sslSupport, int supportedAuthMethods,
-                                   boolean enableAuthn, boolean enableGroupLookup,
-                                   long trustDuration) {
-    return new AuthnMechLdap(name, hostport, bindDn, password, searchBase,
-                             userSearchFilter, groupSearchFilter, sslSupport,
-                             supportedAuthMethods, enableAuthn, enableGroupLookup,
-                             trustDuration);
-  }
-
-  private AuthnMechLdap(String name, String hostport, String bindDn, String password,
-                        String searchBase, String userSearchFilter, String groupSearchFilter,
-                        int sslSupport, int supportedAuthMethods, boolean enableAuthn,
-                        boolean enableGroupLookup, long trustDuration) {
-    super(name);
-    this.hostport = hostport;
-    this.bindDn = bindDn;
-    this.password = password;
-    this.searchBase = searchBase;
-    this.userSearchFilter = userSearchFilter;
-    this.groupSearchFilter = groupSearchFilter;
-    this.sslSupport = sslSupport;
-    this.supportedAuthMethods = supportedAuthMethods;
-    this.enableAuthn = enableAuthn;
-    this.enableGroupLookup = enableGroupLookup;
-    this.trustDuration = trustDuration;
-  }
-
-  public static AuthnMechLdap makeEmpty() {
-    return new AuthnMechLdap();
-  }
-
-  private AuthnMechLdap() {
-    super();
-    this.hostport = null;
-    this.bindDn = null;
-    this.password = null;
-    this.searchBase = null;
-    this.userSearchFilter = null;
-    this.groupSearchFilter = null;
-    this.sslSupport = 0;
-    this.supportedAuthMethods = 0;
-    this.enableAuthn = false;
-    this.enableGroupLookup = false;
-    this.trustDuration = getDefaultTrustDuration();
-  }
-
-  public String getHostport() {
-    return hostport;
-  }
-
-  public String getBindDn() {
-    return bindDn;
-  }
-
-  public String getPassword() {
-    return password;
-  }
-
-  public String getSearchBase() {
-    return searchBase;
-  }
-
-  public String getUserSearchFilter() {
-    return userSearchFilter;
-  }
-
-  public String getGroupSearchFilter() {
-    return groupSearchFilter;
-  }
-
-  public int getSslSupport() {
-    return sslSupport;
-  }
-
-  public int getSupportedAuthMethods() {
-    return supportedAuthMethods;
-  }
-
-  public boolean isEnableAuthn() {
-    return enableAuthn;
-  }
-
-  public boolean isEnableGroupLookup() {
-    return enableGroupLookup;
-  }
-
-  @Override
-  public long getTrustDuration() {
-    return trustDuration;
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    ImmutableList.Builder<CredentialTransform> builder = ImmutableList.builder();
-    if (isEnableAuthn()) {
-      builder.add(
-          CredentialTransform.make(
-              CredentialTypeSet.PRINCIPAL_AND_PASSWORD,
-              CredentialTypeSet.VERIFIED_PRINCIPAL_AND_PASSWORD));
-    }
-    if (isEnableGroupLookup()) {
-      builder.add(
-          CredentialTransform.make(
-              CredentialTypeSet.VERIFIED_PRINCIPAL,
-              CredentialTypeSet.VERIFIED_GROUPS));
-    }
-    return builder.build();
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getHostport(), getBindDn(), getPassword(), getSearchBase(),
-        getUserSearchFilter(), getGroupSearchFilter(), getSslSupport(), getSupportedAuthMethods(),
-        isEnableAuthn(), isEnableGroupLookup(), getTrustDuration());
-  }
-
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechLdap)) { return false; }
-    AuthnMechLdap mech = (AuthnMechLdap) object;
-    return super.equals(mech)
-        && Objects.equal(getHostport(), mech.getHostport())
-        && Objects.equal(getBindDn(), mech.getBindDn())
-        && Objects.equal(getPassword(), mech.getPassword())
-        && Objects.equal(getSearchBase(), mech.getSearchBase())
-        && Objects.equal(getUserSearchFilter(), mech.getUserSearchFilter())
-        && Objects.equal(getGroupSearchFilter(), mech.getGroupSearchFilter())
-        && Objects.equal(getSslSupport(), mech.getSslSupport())
-        && Objects.equal(getSupportedAuthMethods(), mech.getSupportedAuthMethods())
-        && Objects.equal(isEnableAuthn(), mech.isEnableAuthn())
-        && Objects.equal(isEnableGroupLookup(), mech.isEnableGroupLookup()
-        && Objects.equal(getTrustDuration(), mech.getTrustDuration()));
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(getHostport(), getBindDn(), getPassword(), getSearchBase(),
-        getUserSearchFilter(), getGroupSearchFilter(), getSslSupport(), getSupportedAuthMethods(),
-        isEnableAuthn(), isEnableGroupLookup(), getTrustDuration());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechLdap.class,
-        ProxyTypeAdapter.make(AuthnMechLdap.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechLdap> {
-    boolean enableAuthn;
-    boolean enableGroupLookup;
-    String hostport;
-    String bindDn;
-    String password;
-    String searchBase;
-    String userSearchFilter;
-    String groupSearchFilter;
-    int sslSupport;
-    int supportedAuthMethods;
-    long trustDuration = DEFAULT_TRUST_DURATION;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechLdap mechanism) {
-      super(mechanism);
-      hostport = mechanism.getHostport();
-      bindDn = mechanism.getBindDn();
-      password = mechanism.getPassword();
-      searchBase = mechanism.getSearchBase();
-      userSearchFilter = mechanism.getUserSearchFilter();
-      groupSearchFilter = mechanism.getGroupSearchFilter();
-      sslSupport = mechanism.getSslSupport();
-      supportedAuthMethods = mechanism.getSupportedAuthMethods();
-      enableAuthn = mechanism.isEnableAuthn();
-      enableGroupLookup = mechanism.isEnableGroupLookup();
-      trustDuration = mechanism.getTrustDuration();
-    }
-
-    @Override
-    public AuthnMechLdap build() {
-      return make(name, hostport, bindDn, password, searchBase, userSearchFilter, groupSearchFilter,
-          sslSupport, supportedAuthMethods, enableAuthn, enableGroupLookup, trustDuration);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechNtlm.java b/src/com/google/enterprise/secmgr/config/AuthnMechNtlm.java
deleted file mode 100644
index 035810b..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechNtlm.java
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of an NTLM authentication mechanism.
- */
-@Immutable
-public final class AuthnMechNtlm extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "NTLM";
-  private static final long DEFAULT_TRUST_DURATION = 20 * 60 * 1000;  // 20 mins
-
-  private final String sampleUrl;
-  private final long trustDuration;
-
-  /**
-   * Make a new NTLM mechanism.
-   *
-   * @param sampleUrl A sample URL that requires NTLM authentication.
-   * @param trustDuration The number of milliseconds that successfully
-   *     verified credentials are trusted.  This must be a non-negative number.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechNtlm make(String name, String sampleUrl, long trustDuration) {
-    return new AuthnMechNtlm(name, sampleUrl, trustDuration);
-  }
-
-  /**
-   * Make a new NTLM mechanism with a default trust duration.
-   *
-   * @param sampleUrl A sample URL that requires NTLM authentication.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechNtlm make(String name, String sampleUrl) {
-    return make(name, sampleUrl, getDefaultTrustDuration());
-  }
-
-  private AuthnMechNtlm(String name, String sampleUrl, long trustDuration) {
-    super(name);
-    this.sampleUrl = checkString(sampleUrl);
-    this.trustDuration = checkTrustDuration(trustDuration);
-  }
-
-  /**
-   * Make a new unconfigured NTLM mechanism.
-   */
-  public static AuthnMechNtlm makeEmpty() {
-    return new AuthnMechNtlm();
-  }
-
-  private AuthnMechNtlm() {
-    super();
-    this.sampleUrl = null;
-    this.trustDuration = getDefaultTrustDuration();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  /**
-   * Get the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        CredentialTransform.make(
-            CredentialTypeSet.PRINCIPAL_AND_PASSWORD,
-            CredentialTypeSet.VERIFIED_PRINCIPAL_AND_PASSWORD));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getSampleUrl(), getTrustDuration());
-  }
-
-  @Override
-  public String getSampleUrl() {
-    return sampleUrl;
-  }
-
-  @Override
-  public long getTrustDuration() {
-    return trustDuration;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechNtlm)) { return false; }
-    AuthnMechNtlm mech = (AuthnMechNtlm) object;
-    return super.equals(mech)
-        && Objects.equal(getSampleUrl(), mech.getSampleUrl())
-        && Objects.equal(getTrustDuration(), mech.getTrustDuration());
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(getSampleUrl(), getTrustDuration());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechNtlm.class,
-        ProxyTypeAdapter.make(AuthnMechNtlm.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechNtlm> {
-    String sampleUrl;
-    long trustDuration = DEFAULT_TRUST_DURATION;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechNtlm mechanism) {
-      super(mechanism);
-      sampleUrl = mechanism.getSampleUrl();
-      trustDuration = mechanism.getTrustDuration();
-    }
-
-    @Override
-    public AuthnMechNtlm build() {
-      return make(name, sampleUrl, trustDuration);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechSaml.java b/src/com/google/enterprise/secmgr/config/AuthnMechSaml.java
deleted file mode 100644
index 529624c..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechSaml.java
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of a SAML authentication mechanism.
- */
-@Immutable
-public final class AuthnMechSaml extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "SAML";
-
-  private final String entityId;
-
-  public static AuthnMechSaml make(String name, String entityId) {
-    return new AuthnMechSaml(name, entityId);
-  }
-
-  private AuthnMechSaml(String name, String entityId) {
-    super(name);
-    this.entityId = checkString(entityId);
-  }
-
-  public static AuthnMechSaml makeEmpty() {
-    return new AuthnMechSaml();
-  }
-
-  private AuthnMechSaml() {
-    super();
-    this.entityId = null;
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    return ImmutableList.of(
-        CredentialTransform.make(CredentialTypeSet.NONE, CredentialTypeSet.VERIFIED_PRINCIPAL));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getEntityId());
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechSaml)) { return false; }
-    AuthnMechSaml mech = (AuthnMechSaml) object;
-    return super.equals(mech)
-        && Objects.equal(entityId, mech.getEntityId());
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(entityId);
-  }
-
-  /**
-   * Get the SAML entity ID for this authority.  This ID is used as a key when
-   * looking up SAML metadata that describes the authority.
-   *
-   * @return The SAML entity ID as a string, never null or empty, normally a URI.
-   */
-  public String getEntityId() {
-    return entityId;
-  }
-
-  public static final Predicate<AuthnMechanism> SAML_PREDICATE = new Predicate<AuthnMechanism>() {
-    public boolean apply(AuthnMechanism config) {
-      return (config instanceof AuthnMechSaml);
-    }
-  };
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechSaml.class,
-        ProxyTypeAdapter.make(AuthnMechSaml.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechSaml> {
-    String entityId;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechSaml mechanism) {
-      super(mechanism);
-      entityId = mechanism.getEntityId();
-    }
-
-    @Override
-    public AuthnMechSaml build() {
-      return make(name, entityId);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechSampleUrl.java b/src/com/google/enterprise/secmgr/config/AuthnMechSampleUrl.java
deleted file mode 100644
index a9a99be..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechSampleUrl.java
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.gson.GsonBuilder;
-
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The configuration of a sample-URL check authentication mechanism.
- */
-@Immutable
-public final class AuthnMechSampleUrl extends AuthnMechanism {
-
-  public static final String TYPE_NAME = "SampleUrlCheck";
-  public static final String DEFAULT_RETURN_URL_PARAMETER = "returnPath";
-  private static final long DEFAULT_TRUST_DURATION = 5 * 60 * 1000;  // five minutes
-
-  private final String sampleUrl;
-  private final String redirectUrl;
-  private final String returnUrlParameter;
-  private final long trustDuration;
-
-  /**
-   * Make a new sample-URL cookie mechanism.
-   *
-   * @param sampleUrl A sample URL that requires cookie authentication.
-   * @param redirectUrl A URL to redirect the user agent to in order to get the cookie(s).
-   * @param trustDuration The number of milliseconds that successfully
-   *     verified credentials are trusted.  This must be a non-negative number.
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechSampleUrl make(String name, String sampleUrl, String redirectUrl,
-      String returnUrlParameter, long trustDuration) {
-    return new AuthnMechSampleUrl(name, sampleUrl, redirectUrl, returnUrlParameter, trustDuration);
-  }
-
-  /**
-   * Make a new sample-URL cookie mechanism with a default trust duration.
-   *
-   * @param sampleUrl A sample URL that requires cookie authentication.
-   * @param redirectUrl A URL to redirect the user agent to in order to get the cookie(s).
-   * @return A new mechanism with the given elements.
-   */
-  public static AuthnMechSampleUrl make(String name, String sampleUrl, String redirectUrl) {
-    return make(name, sampleUrl, redirectUrl, getDefaultReturnUrlParameter(),
-        getDefaultTrustDuration());
-  }
-
-  private AuthnMechSampleUrl(String name, String sampleUrl, String redirectUrl,
-      String returnUrlParameter, long trustDuration) {
-    super(name);
-    this.sampleUrl = checkStringOrNull(sampleUrl);
-    this.redirectUrl = checkStringOrNull(redirectUrl);
-    this.returnUrlParameter = checkStringOrNull(returnUrlParameter);
-    this.trustDuration = checkTrustDuration(trustDuration);
-  }
-
-  /**
-   * Make a new unconfigured sample-URL cookie mechanism.
-   */
-  public static AuthnMechSampleUrl makeEmpty() {
-    return new AuthnMechSampleUrl();
-  }
-
-  private AuthnMechSampleUrl() {
-    super();
-    this.sampleUrl = null;
-    this.redirectUrl = null;
-    this.returnUrlParameter = getDefaultReturnUrlParameter();
-    this.trustDuration = getDefaultTrustDuration();
-  }
-
-  @Override
-  public String getTypeName() {
-    return TYPE_NAME;
-  }
-
-  public static String getDefaultReturnUrlParameter() {
-    return DEFAULT_RETURN_URL_PARAMETER;
-  }
-
-  /**
-   * Get the default trust-duration value.
-   */
-  public static long getDefaultTrustDuration() {
-    return DEFAULT_TRUST_DURATION;
-  }
-
-  @Override
-  public List<CredentialTransform> getCredentialTransforms() {
-    if (redirectUrl != null) {
-      return ImmutableList.of();
-    }
-    return ImmutableList.of(
-        CredentialTransform.make(CredentialTypeSet.COOKIES, CredentialTypeSet.VERIFIED_PRINCIPAL),
-        CredentialTransform.make(CredentialTypeSet.COOKIES, CredentialTypeSet.VERIFIED_ALIASES),
-        CredentialTransform.make(CredentialTypeSet.COOKIES, CredentialTypeSet.VERIFIED_GROUPS));
-  }
-
-  @Override
-  public AuthnMechanism copyWithNewName(String name) {
-    return make(name, getSampleUrl(), getRedirectUrl(), getReturnUrlParameter(),
-        getTrustDuration());
-  }
-
-  @Override
-  public String getSampleUrl() {
-    return sampleUrl;
-  }
-
-  /**
-   * Gets the redirect URL associated with this authority.
-   *
-   * @return The redirect URL as a string, or {@code null} if none exists.
-   */
-  public String getRedirectUrl() {
-    return redirectUrl;
-  }
-
-  /**
-   * Gets the return-URL parameter associated with this authority.
-   *
-   * This is the name of the request/CGI param we set on an outbound redirect,
-   * which tells the server on the receiving end of the redirect where to
-   * redirect back to once it's done.
-   *
-   * The default value for this is {@code "returnPath"}.
-   *
-   * @return The return url parameter string, or {@code null} for default.
-   */
-  public String getReturnUrlParameter() {
-    return returnUrlParameter;
-  }
-
-  @Override
-  public long getTrustDuration() {
-    return trustDuration;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnMechSampleUrl)) { return false; }
-    AuthnMechSampleUrl mech = (AuthnMechSampleUrl) object;
-    return super.equals(mech)
-        && Objects.equal(getSampleUrl(), mech.getSampleUrl())
-        && Objects.equal(getRedirectUrl(), mech.getRedirectUrl())
-        && Objects.equal(getReturnUrlParameter(), mech.getReturnUrlParameter())
-        && Objects.equal(getTrustDuration(), mech.getTrustDuration());
-  }
-
-  @Override
-  public int hashCode() {
-    return super.hashCode(getSampleUrl(), getRedirectUrl(), getReturnUrlParameter(),
-        getTrustDuration());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechSampleUrl.class,
-        ProxyTypeAdapter.make(AuthnMechSampleUrl.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy extends MechanismProxy<AuthnMechSampleUrl> {
-    String sampleUrl;
-    String redirectUrl;
-    String returnUrlParameter = DEFAULT_RETURN_URL_PARAMETER;
-    long trustDuration = DEFAULT_TRUST_DURATION;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnMechSampleUrl mechanism) {
-      super(mechanism);
-      sampleUrl = mechanism.getSampleUrl();
-      redirectUrl = mechanism.getRedirectUrl();
-      returnUrlParameter = mechanism.getReturnUrlParameter();
-      trustDuration = mechanism.getTrustDuration();
-    }
-
-    @Override
-    public AuthnMechSampleUrl build() {
-      return make(name, sampleUrl, redirectUrl, returnUrlParameter, trustDuration);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthnMechanism.java b/src/com/google/enterprise/secmgr/config/AuthnMechanism.java
deleted file mode 100644
index 5754e81..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthnMechanism.java
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import java.util.Locale;
-import java.util.regex.Pattern;
-
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * The configuration of an authentication mechanism.  This is the base class for
- * all mechanisms; individual mechanisms inherit from here.
- */
-@ThreadSafe
-public abstract class AuthnMechanism {
-  private static final int CONFIG_NAME_MAX_LENGTH = 200;
-  private static final Pattern CONFIG_NAME_PATTERN
-      = Pattern.compile("^[a-zA-Z0-9_][a-zA-Z0-9_-]*$");
-
-  private final String name;
-  private final AuthnAuthority authority;
-
-  protected AuthnMechanism() {
-    name = null;
-    authority = AuthnAuthority.make();
-  }
-
-  protected AuthnMechanism(String name) {
-    // TODO(cph): eliminate name == null once all callers supply real names.
-    // Right now the only callers with name == null are unit tests.
-    this.name = name;
-    if (name == null) {
-      authority = AuthnAuthority.make();
-    } else {
-      Preconditions.checkArgument(isValidConfigName(name), "Invalid mechanism name: %s", name);
-      authority = AuthnAuthority.make(name);
-    }
-  }
-
-  /**
-   * Is a given string a valid name for a mechanism or credential group?  A
-   * valid name is between 1 and 200 characters and consists only of ASCII
-   * alphanumerics, the underscore character, and the hyphen character.  The
-   * first character may not be a hyphen.
-   *
-   * @param name The string to test for validity.
-   * @return True only if the string is valid.
-   */
-  public static boolean isValidConfigName(String name) {
-    return name != null
-        && !name.isEmpty()
-        && name.length() <= CONFIG_NAME_MAX_LENGTH
-        && CONFIG_NAME_PATTERN.matcher(name).matches();
-  }
-
-  /**
-   * Check a string argument that's allowed to be null.  Disallows empty
-   * strings.  May return a modified string; e.g. may run .trim() on the
-   * argument.
-   *
-   * @param string The string to check.
-   * @return A checked string that is possibly different from the argument.
-   * @throws IllegalArgumentException if the input string is empty.
-   */
-  protected static String checkStringOrNull(String string) {
-    Preconditions.checkArgument(string == null || !string.isEmpty());
-    return string;
-  }
-
-  /**
-   * Check a string argument.  Disallows null and empty strings.  May return a
-   * modified string; e.g. may run .trim() on the argument.
-   *
-   * @param string The string to check.
-   * @return A checked string that is possibly different from the argument.
-   * @throws IllegalArgumentException if the input string is null or empty.
-   */
-  protected static String checkString(String string) {
-    Preconditions.checkArgument(string != null && !string.isEmpty());
-    return string;
-  }
-
-  /**
-   * Check a URL string argument.  Disallows null and non-well-formed strings.
-   * May return a modified string; e.g. may run .trim() on the argument.
-   *
-   * @param string The URL string to check.
-   * @return A checked URL string that is possibly different from the argument.
-   * @throws IllegalArgumentException if the input string is null or not well formed.
-   */
-  protected static String checkUrlString(String string) {
-    try {
-      return (new URL(checkString(string))).toString();
-    } catch (MalformedURLException e) {
-      throw new IllegalArgumentException(e);
-    }
-  }
-
-  /**
-   * Check a trust-duration argument.
-   *
-   * @param trustDuration The trust-duration argument to check.
-   * @return A checked value.
-   * @throws IllegalArgumentException if the argument is invalid.
-   */
-  protected static long checkTrustDuration(long trustDuration) {
-    Preconditions.checkArgument(trustDuration >= 0);
-    return trustDuration;
-  }
-
-  /**
-   * Get the type name of the mechanism.
-   *
-   * @return The type name, never null or empty.
-   */
-  public abstract String getTypeName();
-
-  /**
-   * @return An immutable list of the transformations this mechanism implements.
-   */
-  public abstract List<CredentialTransform> getCredentialTransforms();
-
-  /**
-   * Can this mechanism use ULF credentials?
-   */
-  public boolean canUseUlfCredentials() {
-    return Iterables.any(getCredentialTransforms(),
-        new Predicate<CredentialTransform>() {
-          public boolean apply(CredentialTransform credentialTransform) {
-            CredentialTypeSet inputs = credentialTransform.getInputs();
-            return !inputs.getAreVerified()
-                && inputs.getElements().containsAll(
-                    CredentialTypeSet.PRINCIPAL_AND_PASSWORD.getElements());
-          }
-        });
-  }
-
-  /**
-   * Return a copy of the current mechanism, with a given name.
-   *
-   * @param name The new name.
-   * @return A copy of the current mechanism with the new name.
-   */
-  public abstract AuthnMechanism copyWithNewName(String name);
-
-  /**
-   * @return This mechanism's name.
-   */
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * @return This mechanism's authority.
-   */
-  public AuthnAuthority getAuthority() {
-    return authority;
-  }
-
-  public static Function<AuthnMechanism, AuthnAuthority> getAuthorityFunction() {
-    return AUTHORITY_FUNCTION;
-  }
-
-  private static final Function<AuthnMechanism, AuthnAuthority> AUTHORITY_FUNCTION
-      = new Function<AuthnMechanism, AuthnAuthority>() {
-          @Override
-          public AuthnAuthority apply(AuthnMechanism mechanism) {
-            return mechanism.getAuthority();
-          }
-        };
-
-  /**
-   * A sample URL to GET for credential verification.
-   *
-   * @return The mechanism's sample URL as a string, or null if none.
-   */
-  public String getSampleUrl() {
-    throw new UnsupportedOperationException();
-  }
-
-  /**
-   * For how many milliseconds does this mechanism trust newly-verified
-   * credentials?
-   *
-   * @return The number of milliseconds, always a non-negative number.
-   */
-  public long getTrustDuration() {
-    throw new UnsupportedOperationException();
-  }
-
-  protected boolean equals(AuthnMechanism other) {
-    return getName() == null
-        || other.getName() == null
-        || getName().equalsIgnoreCase(other.getName());
-  }
-
-  protected int hashCode(Object... objects) {
-    Object[] copy = new Object[objects.length + 1];
-    copy[0] = (getName() != null)
-        ? getName().toLowerCase(Locale.US)
-        : null;
-    for (int i = 0; i < objects.length; i += 1) {
-      copy[i + 1] = objects[i];
-    }
-    return Objects.hashCode(copy);
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnMechanism.class,
-        TypeAdapters.dispatch(
-            ImmutableList.of(
-                AuthnMechBasic.class,
-                AuthnMechClient.class,
-                AuthnMechConnector.class,
-                AuthnMechForm.class,
-                AuthnMechKerberos.class,
-                AuthnMechLdap.class,
-                AuthnMechNtlm.class,
-                AuthnMechSaml.class,
-                AuthnMechSampleUrl.class)));
-  }
-
-  /** A base class for type proxies of sub-classes. */
-  protected abstract static class MechanismProxy<T extends AuthnMechanism>
-      implements TypeProxy<T> {
-    public String name;
-
-    protected MechanismProxy() {
-    }
-
-    protected MechanismProxy(AuthnMechanism mechanism) {
-      name = mechanism.getName();
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/AuthzMechanism.java b/src/com/google/enterprise/secmgr/config/AuthzMechanism.java
deleted file mode 100644
index fd80ce1..0000000
--- a/src/com/google/enterprise/secmgr/config/AuthzMechanism.java
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-/**
- * @author meghna@google.com (Meghna Dhar)
- */
-public enum AuthzMechanism {
-  CACHE,
-  CONNECTOR,
-  DENY,
-  HEADREQUEST,
-  POLICY,
-  SAML,
-}
diff --git a/src/com/google/enterprise/secmgr/config/ConfigCodec.java b/src/com/google/enterprise/secmgr/config/ConfigCodec.java
deleted file mode 100644
index f0aaa6a..0000000
--- a/src/com/google/enterprise/secmgr/config/ConfigCodec.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.io.Writer;
-
-/**
- * A base class for implementing a configuration encode/decode class.
- */
-public abstract class ConfigCodec {
-
-  /**
-   * Decode a configuration from a string.
-   *
-   * @param string The string to decode.
-   * @return A configuration.
-   * @throws IOException if there are errors while reading the configuration.
-   * @throws ConfigException if the configuration is malformed.
-   */
-  public SecurityManagerConfig readConfig(String string)
-      throws IOException, ConfigException {
-    return readConfig(new StringReader(string));
-  }
-
-  /**
-   * Encode a configuration as a string.
-   *
-   * @param config The configuration to be encoded.
-   * @return The encoded string.
-   * @throws IOException if there are errors while writing the configuration.
-   */
-  public String configToString(SecurityManagerConfig config) throws IOException {
-    Writer writer = new StringWriter();
-    writeConfig(config, writer);
-    return writer.toString();
-  }
-
-  /**
-   * Read and decode a configuration from a given source.
-   *
-   * @param reader The source to read the encoded configuration from.
-   * @return A configuration.
-   * @throws IOException if there are errors while reading the configuration.
-   * @throws ConfigException if the configuration is malformed.
-   */
-  public SecurityManagerConfig readConfig(Reader reader)
-      throws IOException, ConfigException {
-    SecurityManagerConfig config = readConfigInternal(reader);
-    guaranteeValidConfig(config);
-    return config;
-  }
-
-  /**
-   * Read and decode a configuration from a given file.
-   *
-   * @param file The file to read the encoded configuration from.
-   * @return A configuration.
-   * @throws IOException if there are errors while reading the configuration.
-   * @throws ConfigException if the configuration is malformed.
-   */
-  public SecurityManagerConfig readConfig(File file)
-      throws IOException, ConfigException {
-    Reader reader = new FileReader(file);
-    try {
-      return readConfig(reader);
-    } finally {
-      reader.close();
-    }
-  }
-
-  protected abstract SecurityManagerConfig readConfigInternal(Reader reader)
-      throws IOException, ConfigException;
-
-  /**
-   * Encode and write a configuration to a given sink.
-   *
-   * @param config The configuration to be encoded.
-   * @param writer The sink to write the encoded configuration to.
-   * @throws IOException if there are errors while writing the configuration.
-   */
-  public void writeConfig(SecurityManagerConfig config, Writer writer) throws IOException {
-    guaranteeValidConfig(config);
-    writeConfigInternal(config, writer);
-  }
-
-  protected abstract void writeConfigInternal(SecurityManagerConfig config, Writer writer)
-      throws IOException;
-
-  private void guaranteeValidConfig(SecurityManagerConfig config) {
-    if (!isValidConfig(config)) {
-      throw new IllegalStateException("Config is not valid: " + config);
-    }
-  }
-
-  /**
-   * A valid config must contain a "default" group and that group must require a
-   * username, be non-optional, and non-empty.  This in turn ensures that a saml
-   * assertion from the security manager will always contain a username which
-   * can in turn be used when creating policy ACLs.
-   *
-   * TODO(martincochran): ensure that EFE gets the right username and/or that
-   * the correct saml subject is generated by the security manager.
-   */
-  private boolean isValidConfig(SecurityManagerConfig config) {
-
-    return true;
-    /* TODO(kstillson): I'm disabling this check.  It was added to address
-     * to address the concern that PVI assignment may not be stable- specifically,
-     * user1 has a forms auth cookie before any interaction with the GSA, if the
-     * default CG does not insist on requires-username, then CG will be satisfied
-     * but no username is set, so the PVI could come from somewhere else (e.g.
-     * kerberos).  However, user2 has no cookie, so they get a ULF, and the PVI
-     * is set by their forms login.  That is a problem, however, this solution
-     * is too drastic, and eliminates numerous valid use-cases (such as a sec-mgr
-     * that does nothing but a single forms-auth CG that doesn't need a username).
-     * So We're going to have to find a more subtle solution to the original
-     * problem.
-
-    if (config.isEmpty()) {
-      return true;
-    }
-    boolean defaultGroupEmpty = false;
-    boolean someGroupNonEmpty = false;
-
-    for (CredentialsGroup group : config) {
-      if ("default".equalsIgnoreCase(group.getName())) {
-        if (!group.getRequiresUsername()) {
-          return false;
-        }
-        if (group.getIsOptional()) {
-          return false;
-        }
-        if (!group.getElements().isEmpty()) {
-          return true;
-        }
-      }
-      if (!group.getElements().isEmpty()) {
-        someGroupNonEmpty = true;
-      }
-    }
-    return !someGroupNonEmpty;
-    */
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/ConfigException.java b/src/com/google/enterprise/secmgr/config/ConfigException.java
deleted file mode 100644
index 89418ea..0000000
--- a/src/com/google/enterprise/secmgr/config/ConfigException.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-/**
- * An exception that's thrown when a {@link ConfigCodec} has trouble parsing a
- * configuration string.
- */
-public class ConfigException extends Exception {
-
-  public ConfigException(String message) { super(message); }
-
-  public ConfigException(Throwable e) { super(e); }
-
-  public ConfigException(String message, Throwable e) { super(message, e); }
-}
diff --git a/src/com/google/enterprise/secmgr/config/ConfigModule.java b/src/com/google/enterprise/secmgr/config/ConfigModule.java
deleted file mode 100644
index fd55612..0000000
--- a/src/com/google/enterprise/secmgr/config/ConfigModule.java
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.gson.GsonBuilder;
-/*import com.google.inject.AbstractModule;
-import com.google.inject.name.Names;*/
-
-/**
- * Guice configuration for this package.
- */
-public final class ConfigModule /*extends AbstractModule*/ {
-
-  private final String configFilename;
-
-  public ConfigModule(String configFilename) {
-    this.configFilename = configFilename;
-  }
-
-/*  @Override
-  protected void configure() {
-    bind(ConfigCodec.class).to(JsonConfig.class);
-    bind(ConfigSingleton.class);
-    bind(FlexAuthorizer.class).to(FlexAuthorizerImpl.class);
-    bindConstant()
-        .annotatedWith(Names.named("configFile"))
-        .to(configFilename);
-    requestStaticInjection(ConfigSingleton.class);
-  }*/
-
-  public static void registerTypeAdapters(GsonBuilder builder) {
-    AuthnAuthority.registerTypeAdapters(builder);
-    AuthnMechBasic.registerTypeAdapters(builder);
-    AuthnMechClient.registerTypeAdapters(builder);
-    AuthnMechConnector.registerTypeAdapters(builder);
-    AuthnMechForm.registerTypeAdapters(builder);
-    AuthnMechKerberos.registerTypeAdapters(builder);
-    AuthnMechLdap.registerTypeAdapters(builder);
-    AuthnMechNtlm.registerTypeAdapters(builder);
-    AuthnMechSaml.registerTypeAdapters(builder);
-    AuthnMechSampleUrl.registerTypeAdapters(builder);
-    AuthnMechanism.registerTypeAdapters(builder);
-    ConfigParams.registerTypeAdapters(builder);
-    ConnMgrInfo.registerTypeAdapters(builder);
-    CredentialGroup.registerTypeAdapters(builder);
-    FlexAuthorizerImpl.registerTypeAdapters(builder);
-    FlexAuthzRoutingTableEntry.registerTypeAdapters(builder);
-    FlexAuthzRule.registerTypeAdapters(builder);
-    ParamName.registerTypeAdapters(builder);
-    SecurityManagerConfig.registerTypeAdapters(builder);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/ConfigParams.java b/src/com/google/enterprise/secmgr/config/ConfigParams.java
deleted file mode 100644
index c8a8aae..0000000
--- a/src/com/google/enterprise/secmgr/config/ConfigParams.java
+++ /dev/null
@@ -1,209 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonDeserializationContext;
-import com.google.gson.JsonDeserializer;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonSerializationContext;
-import com.google.gson.JsonSerializer;
-
-import java.lang.reflect.Type;
-import java.util.EnumSet;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * An generalized configuration-parameters implementation.  This can store any
- * named parameter, of any type.
- *
- * @see ParamName
- */
-@Immutable
-public final class ConfigParams {
-
-  private final ImmutableMap<ParamName, Object> map;
-
-  private ConfigParams(ImmutableMap<ParamName, Object> map) {
-    this.map = map;
-  }
-
-  /**
-   * Gets the set of keys.
-   *
-   * @return The keys.
-   */
-  public static EnumSet<ParamName> keySet() {
-    return EnumSet.allOf(ParamName.class);
-  }
-
-  /**
-   * Gets the value of a parameter.
-   *
-   * @param key The name of the parameter to retrieve.
-   * @return The value of the parameter.
-   */
-  public Object get(ParamName key) {
-    return map.get(key);
-  }
-
-  /**
-   * Gets the value of a parameter, casting it to a given type.
-   *
-   * @param key The name of the parameter to retrieve.
-   * @param valueClass The class to cast the value to.
-   * @return The value of the parameter.
-   * @throws IllegalArgumentException if <code>valueClass</code> isn't
-   *     assignable from the parameter's value.
-   */
-  public <T> T get(ParamName key, Class<T> valueClass) {
-    Preconditions.checkArgument(valueClass.isAssignableFrom(key.getValueClass()));
-    return valueClass.cast(get(key));
-  }
-
-  /**
-   * Gets a default set of configuration parameters.
-   *
-   * @return The default set.
-   */
-  public static ConfigParams makeDefault() {
-    return builder().build();
-  }
-
-  /**
-   * Gets a new configuration-parameters builder.
-   *
-   * @return A new builder.
-   */
-  public static Builder builder() {
-    return new Builder(null);
-  }
-
-  /**
-   * Gets a new configuration-parameters builder initialized with defaults.
-   *
-   * @param defaultValues A set of configuration parameters to use as defaults.
-   * @return A new builder.
-   */
-  public static Builder builder(ConfigParams defaultValues) {
-    Preconditions.checkNotNull(defaultValues);
-    return new Builder(defaultValues);
-  }
-
-  /**
-   * A builder factory for configuration parameters.
-   */
-  public static final class Builder {
-    private final ConfigParams defaultValues;
-    private final ImmutableMap.Builder<ParamName, Object> mapBuilder;
-    private final EnumSet<ParamName> unseen;
-
-    private Builder(ConfigParams defaultValues) {
-      this.defaultValues = defaultValues;
-      mapBuilder = ImmutableMap.builder();
-      unseen = EnumSet.allOf(ParamName.class);
-    }
-
-    /**
-     * Set the value of a parameter.
-     *
-     * @param key The parameter's name.
-     * @param value The parameter's value.
-     * @return This builder, for programming convenience.
-     * @throws IllegalArgumentException if the value isn't valid for this parameter.
-     */
-    public Builder put(ParamName key, Object value) {
-      Preconditions.checkArgument(key.isValidValue(value));
-      mapBuilder.put(key, value);
-      unseen.remove(key);
-      return this;
-    }
-
-    /**
-     * @return The completed parameters object.
-     */
-    public ConfigParams build() {
-      for (ParamName key : unseen) {
-        mapBuilder.put(key,
-            (defaultValues == null)
-            ? key.getDefaultValue()
-            : defaultValues.get(key));
-      }
-      return new ConfigParams(mapBuilder.build());
-    }
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof ConfigParams)) { return false; }
-    ConfigParams other = (ConfigParams) object;
-    for (ParamName key : keySet()) {
-      if (!get(key).equals(other.get(key))) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    EnumSet<ParamName> keys = keySet();
-    Object[] values = new Object[keys.size()];
-    int i = 0;
-    for (ParamName key : keys) {
-      values[i++] = get(key);
-    }
-    return Objects.hashCode(values);
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(ConfigParams.class, new LocalTypeAdapter());
-  }
-
-  static final class LocalTypeAdapter
-      implements JsonSerializer<ConfigParams>, JsonDeserializer<ConfigParams> {
-    LocalTypeAdapter() {
-    }
-
-    @Override
-    public JsonElement serialize(ConfigParams params, Type type, JsonSerializationContext context) {
-      JsonObject jo = new JsonObject();
-      for (ParamName key : ConfigParams.keySet()) {
-        jo.add(key.toString(), context.serialize(params.get(key), key.getValueClass()));
-      }
-      return jo;
-    }
-
-    @Override
-    public ConfigParams deserialize(JsonElement src, Type type,
-        JsonDeserializationContext context) {
-      JsonObject jo = src.getAsJsonObject();
-      ConfigParams.Builder builder = ConfigParams.builder();
-      for (ParamName key : ConfigParams.keySet()) {
-        JsonElement je = jo.get(key.toString());
-        if (je != null) {
-          builder.put(key, context.deserialize(je, key.getValueClass()));
-        }
-      }
-      return builder.build();
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/ConfigSingleton.java b/src/com/google/enterprise/secmgr/config/ConfigSingleton.java
index 8853daa..d445578 100644
--- a/src/com/google/enterprise/secmgr/config/ConfigSingleton.java
+++ b/src/com/google/enterprise/secmgr/config/ConfigSingleton.java
@@ -16,22 +16,11 @@
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.enterprise.secmgr.common.FileUtil;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Key;
-import com.google.inject.Singleton;
-import com.google.inject.TypeLiteral;
-import com.google.inject.name.Named;
 
-import java.io.File;
-import java.io.IOException;
 import java.util.Observable;
 import java.util.Observer;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.annotation.concurrent.GuardedBy;
@@ -40,14 +29,11 @@
 /**
  * A singleton class to access configured parameters.
  */
-@Singleton
 @ThreadSafe
 public class ConfigSingleton {
   private static final Logger LOGGER = Logger.getLogger(ConfigSingleton.class.getName());
 
-  @Inject private static Injector injector;
-  @Inject private static ConfigSingleton instance;
-  @GuardedBy("class") private static SecurityManagerConfig configOverride = null;
+  private static ConfigSingleton instance;
   @GuardedBy("class") private static Gson gson;
   private static final LocalObservable observable = new LocalObservable();
 
@@ -58,58 +44,16 @@
     }
   }
 
-  private final ConfigCodec configCodec;
-  private final String configFilename;
-  /** The modification time of the configuration file when last read. */
-  @GuardedBy("this") private long configTime;
-  /** The parsed configuration file. */
-  @GuardedBy("this") private SecurityManagerConfig config;
-
-  @Inject
-  private ConfigSingleton(ConfigCodec configCodec, @Named("configFile") String configFilename) {
-    Preconditions.checkNotNull(configCodec);
-    Preconditions.checkArgument(!Strings.isNullOrEmpty(configFilename));
-    this.configCodec = configCodec;
-    this.configFilename = configFilename;
+  private ConfigSingleton() {
     resetInternal();
   }
 
-  /**
-   * @return The application's Guice injector.
-   */
-  public static Injector getInjector() {
-    return injector;
-  }
-
-  /**
-   * A convenience method that invokes the injector.
-   *
-   * @param clazz The class to instantiate.
-   * @return An instance of the given class.
-   */
-  public static <T> T getInstance(Class<T> clazz) {
-    return injector.getInstance(clazz);
-  }
-
-  /**
-   * A convenience method that invokes the injector.
-   *
-   * @param type The type to instantiate.
-   * @return An instance of the given type.
-   */
-  public static <T> T getInstance(TypeLiteral<T> type) {
-    return injector.getInstance(Key.get(type));
-  }
-
   @VisibleForTesting
   public static synchronized void reset() {
-    configOverride = null;
     instance.resetInternal();
   }
 
   private synchronized void resetInternal() {
-    configTime = 0;
-    config = null;
   }
 
   /**
@@ -147,115 +91,4 @@
     Preconditions.checkNotNull(gson);
     return gson;
   }
-
-  /**
-   * @return The current configuration.
-   * @throws IOException if there are I/O errors reading the configuration.
-   */
-  public static synchronized SecurityManagerConfig getConfig()
-      throws IOException {
-    return (configOverride != null) ? configOverride : getConfigNoOverride();
-  }
-
-  @VisibleForTesting
-  public static synchronized SecurityManagerConfig getConfigNoOverride()
-      throws IOException {
-    return instance.getConfigInternal();
-  }
-
-  @VisibleForTesting
-  public static synchronized void setConfig(SecurityManagerConfig config) {
-    configOverride = config;
-    setChanged();
-  }
-
-  private synchronized SecurityManagerConfig getConfigInternal()
-      throws IOException {
-    File file = FileUtil.getContextFile(configFilename);
-    // Check the config file's mod time; if it hasn't changed since the last
-    // successful read, use the cached value.  Otherwise, try reading the config
-    // file.  Go around the loop until the mod time before the read and the mod
-    // time after the read are the same.  This detects changes to the file
-    // during the read.
-    while (true) {
-      long time = file.lastModified();
-      if (time == 0) {
-        throw new IOException("No such file: " + file);
-      }
-      if (time == configTime) {
-        break;
-      }
-      try {
-        config = configCodec.readConfig(file);
-      } catch (ConfigException e) {
-        LOGGER.log(Level.SEVERE, "Error parsing config file. Returning default config.", e);
-        config = SecurityManagerConfig.makeDefault();
-      }
-      configTime = time;
-      LOGGER.fine("Config:\n" + config);
-      observable.setChanged();
-    }
-    observable.notifyObservers();
-    return config;
-  }
-
-  /** @see SecurityManagerConfig#getAclGroupsFilename */
-  public static String getAclGroupsFilename() throws IOException {
-    return getConfig().getAclGroupsFilename();
-  }
-
-  /** @see SecurityManagerConfig#getAclUrlsFilename */
-  public static String getAclUrlsFilename() throws IOException {
-    return getConfig().getAclUrlsFilename();
-  }
-
-  /** @see SecurityManagerConfig#getCertificateAuthoritiesFilename */
-  public static String getCertificateAuthoritiesFilename() throws IOException {
-    return getConfig().getCertificateAuthoritiesFilename();
-  }
-
-  /** @see SecurityManagerConfig#getConnectorManagerUrls */
-  public static Iterable<String> getConnectorManagerUrls() throws IOException {
-    return getConfig().getConnectorManagerUrls();
-  }
-
-  /** @see SecurityManagerConfig#getDenyRulesFilename */
-  public static String getDenyRulesFilename() throws IOException {
-    return getConfig().getDenyRulesFilename();
-  }
-
-  /** @see SecurityManagerConfig#getGlobalBatchRequestTimeout */
-  public static Float getGlobalBatchRequestTimeout() throws IOException {
-    return getConfig().getGlobalBatchRequestTimeout();
-  }
-
-  /** @see SecurityManagerConfig#getGlobalSingleRequestTimeout */
-  public static Float getGlobalSingleRequestTimeout() throws IOException {
-    return getConfig().getGlobalSingleRequestTimeout();
-  }
-
-  /** @see SecurityManagerConfig#getSamlMetadataFilename */
-  public static String getSamlMetadataFilename() throws IOException {
-    return getConfig().getSamlMetadataFilename();
-  }
-
-  /** @see SecurityManagerConfig#getServerCertificateFilename */
-  public static String getServerCertificateFilename() throws IOException {
-    return getConfig().getServerCertificateFilename();
-  }
-
-  /** @see SecurityManagerConfig#getSigningCertificateFilename */
-  public static String getSigningCertificateFilename() throws IOException {
-    return getConfig().getSigningCertificateFilename();
-  }
-
-  /** @see SecurityManagerConfig#getSigningKeyFilename */
-  public static String getSigningKeyFilename() throws IOException {
-    return getConfig().getSigningKeyFilename();
-  }
-
-  /** @see SecurityManagerConfig#getStunnelPort */
-  public static int getStunnelPort() throws IOException {
-    return getConfig().getStunnelPort();
-  }
 }
diff --git a/src/com/google/enterprise/secmgr/config/ConnMgrInfo.java b/src/com/google/enterprise/secmgr/config/ConnMgrInfo.java
deleted file mode 100644
index 74079eb..0000000
--- a/src/com/google/enterprise/secmgr/config/ConnMgrInfo.java
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A structure describing a set of configured connector managers.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class ConnMgrInfo {
-
-  /**
-   * A structure describing a single connector manager.
-   */
-  @Immutable
-  @ParametersAreNonnullByDefault
-  public static final class Entry {
-    @Nonnull private final String name;
-    @Nonnull private final String url;
-
-    private Entry(String name, String url) {
-      this.name = name;
-      this.url = url;
-    }
-
-    /**
-     * Makes a new connector-manager entry.
-     *
-     * @param name The name of the connector manager.
-     * @param url The URL for the connector manager.
-     * @return An entry containing the above information.
-     */
-    @Nonnull
-    public static Entry make(String name, String url) {
-      Preconditions.checkNotNull(name);
-      Preconditions.checkNotNull(url);
-      return new Entry(name, url);
-    }
-
-    /**
-     * Gets the name of the connector manager represented by this entry.
-     *
-     * @return The connector-manager name.
-     */
-    @Nonnull
-    public String getName() {
-      return name;
-    }
-
-    /**
-     * Gets the URL of the connector manager represented by this entry.
-     *
-     * @return The connector-manager URL as a string.
-     */
-    @Nonnull
-    public String getUrl() {
-      return url;
-    }
-
-    @Override
-    public boolean equals(Object object) {
-      if (object == this) { return true; }
-      if (!(object instanceof Entry)) { return false; }
-      Entry other = (Entry) object;
-      return Objects.equal(getName(), other.getName())
-          && Objects.equal(getUrl(), other.getUrl());
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(getName(), getUrl());
-    }
-
-    @Override
-    public String toString() {
-      return ConfigSingleton.getGson().toJson(this);
-    }
-  }
-
-  @Nonnull private final ImmutableSet<Entry> entries;
-
-  private ConnMgrInfo(ImmutableSet<Entry> entries) {
-    this.entries = entries;
-  }
-
-  /**
-   * Makes a new connector-manager info object.
-   *
-   * @param entries The per-connector-manager entries.
-   * @return A new set with the given entries.
-   */
-  @Nonnull
-  public static ConnMgrInfo make(Iterable<Entry> entries) {
-    return new ConnMgrInfo(ImmutableSet.copyOf(entries));
-  }
-
-  /**
-   * Gets the per-connector-manager entries for this object.
-   *
-   * @return The entries as an immutable set.
-   */
-  @Nonnull
-  public ImmutableSet<Entry> getEntries() {
-    return entries;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof ConnMgrInfo)) { return false; }
-    ConnMgrInfo other = (ConnMgrInfo) object;
-    return Objects.equal(getEntries(), other.getEntries());
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(getEntries());
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  /**
-   * Decodes string-encoded connector-manager info.
-   *
-   * @param string The encoded info.
-   * @return The decoded info.
-   */
-  public static ConnMgrInfo valueOf(String string) {
-    return ConfigSingleton.getGson().fromJson(string, ConnMgrInfo.class);
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(new TypeToken<ImmutableSet<Entry>>() {}.getType(),
-        TypeAdapters.immutableSet());
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/CredentialGroup.java b/src/com/google/enterprise/secmgr/config/CredentialGroup.java
deleted file mode 100644
index 200d447..0000000
--- a/src/com/google/enterprise/secmgr/config/CredentialGroup.java
+++ /dev/null
@@ -1,320 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Lists;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-
-import java.util.Collection;
-import java.util.List;
-
-import javax.annotation.concurrent.Immutable;
-import javax.annotation.concurrent.NotThreadSafe;
-
-/**
- * A "credential group" is a set of authentication mechanisms that are defined
- * to share a common username and password.
- */
-@Immutable
-public class CredentialGroup {
-
-  public static final String DEFAULT_NAME = "Default";
-
-  private final String name;
-  private final AuthnAuthority authority;
-  private final String displayName;
-  private final boolean requiresUsername;   // Not satisfied until a username is known.
-  private final boolean requiresPassword;   // Not satisfied until a password is known.
-  private final boolean isOptional;         // Can be satisfied given blank username & password.
-  private final ImmutableList<AuthnMechanism> mechanisms;
-
-  private CredentialGroup(String name, String displayName, boolean requiresUsername,
-      boolean requiresPassword, boolean isOptional, List<AuthnMechanism> mechanisms) {
-    Preconditions.checkArgument(name != null && AuthnMechanism.isValidConfigName(name),
-        "Invalid credential-group name: %s", name);
-    this.name = name;
-    authority = AuthnAuthority.make(name);
-    this.displayName = (displayName != null) ? displayName : name;
-    this.requiresUsername = requiresUsername;
-    this.requiresPassword = requiresPassword;
-    this.isOptional = isOptional;
-    this.mechanisms = ImmutableList.copyOf(mechanisms);
-  }
-
-  /**
-   * Get a credential-group builder.
-   *
-   * @param name The name of the group; used in ACLs.
-   * @param displayName The name of the group as presented to end users.
-   * @param requiresUsername Does the group require a verified username?
-   * @param requiresPassword Does the group require a verified password?
-   * @param isOptional False if the credentials for this group must be supplied.
-   * @return A credential-group builder with given initial settings and no mechanisms.
-   */
-  public static Builder builder(String name, String displayName, boolean requiresUsername,
-        boolean requiresPassword, boolean isOptional) {
-    return new Builder(name, displayName, requiresUsername, requiresPassword, isOptional);
-  }
-
-  /**
-   * Get a credential-group builder.
-   *
-   * @param group A credential group to get the initial settings from.
-   * @return A credential-group builder initialized with the given credential group.
-   */
-  public static Builder builder(CredentialGroup group) {
-    Builder newBuilder = new Builder(group.getName(), group.getDisplayName(),
-        group.getRequiresUsername(), group.getRequiresPassword(), group.getIsOptional());
-    newBuilder.addMechanisms(group.getMechanisms());
-    return newBuilder;
-  }
-
-  /**
-   * Get a credential-group builder.
-   *
-   * @return A credential-group builder with default initial settings and no mechanisms.
-   */
-  public static Builder builder() {
-    return builder(DEFAULT_NAME, DEFAULT_NAME, true, false, false);
-  }
-
-  /**
-   * A builder factor for credential-group instances.
-   */
-  @NotThreadSafe
-  public static final class Builder {
-
-    private String name;
-    private String displayName;
-    private boolean requiresUsername;
-    private boolean requiresPassword;
-    private boolean isOptional;
-    private List<AuthnMechanism> mechanisms;
-
-    private Builder(String name, String displayName, boolean requiresUsername,
-        boolean requiresPassword, boolean isOptional) {
-      this.name = name;
-      this.displayName = displayName;
-      this.requiresUsername = requiresUsername;
-      this.requiresPassword = requiresPassword;
-      this.isOptional = isOptional;
-      this.mechanisms = Lists.newArrayList();
-    }
-
-    public String getName() {
-      return name;
-    }
-
-    public Builder setName(String name) {
-      this.name = name;
-      return this;
-    }
-
-    public Builder setDisplayName(String displayName) {
-      this.displayName = displayName;
-      return this;
-    }
-
-    public Builder setRequiresUsername(boolean requiresUsername) {
-      this.requiresUsername = requiresUsername;
-      return this;
-    }
-
-    public Builder setRequiresPassword(boolean requiresPassword) {
-      this.requiresPassword = requiresPassword;
-      return this;
-    }
-
-    public Builder setIsOptional(boolean isOptional) {
-      this.isOptional = isOptional;
-      return this;
-    }
-
-    public List<AuthnMechanism> getMechanisms() {
-      return mechanisms;
-    }
-
-    public Builder addMechanism(AuthnMechanism mechanism) {
-      mechanisms.add(mechanism);
-      return this;
-    }
-
-    public Builder addMechanism(int index, AuthnMechanism mechanism) {
-      mechanisms.add(index, mechanism);
-      return this;
-    }
-
-    public Builder addMechanisms(Collection<AuthnMechanism> mechanisms) {
-      this.mechanisms.addAll(mechanisms);
-      return this;
-    }
-
-    public AuthnMechanism findMechanism(String name) {
-      for (AuthnMechanism mechanism : mechanisms) {
-        if (name.equalsIgnoreCase(mechanism.getName())) {
-          return mechanism;
-        }
-      }
-      return null;
-    }
-
-    public Builder replaceMechanism(AuthnMechanism mechanism) {
-      AuthnMechanism other = findMechanism(mechanism.getName());
-      Preconditions.checkArgument(other != null,
-          "No existing mechanism with this name: %s", mechanism.getName());
-      mechanisms.remove(other);
-      mechanisms.add(mechanism);
-      return this;
-    }
-
-    public CredentialGroup build() {
-      return new CredentialGroup(name, displayName, requiresUsername, requiresPassword, isOptional,
-          mechanisms);
-    }
-  }
-
-  public String getName() {
-    return name;
-  }
-
-  public AuthnAuthority getAuthority() {
-    return authority;
-  }
-
-  public String getDisplayName() {
-    return displayName;
-  }
-
-  public ImmutableList<AuthnMechanism> getMechanisms() {
-    return mechanisms;
-  }
-
-  public boolean hasMechanismOfType(Class<? extends AuthnMechanism> type) {
-    for (AuthnMechanism mech : mechanisms) {
-      if (type.isInstance(mech)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  public boolean getRequiresUsername() {
-    return requiresUsername;
-  }
-
-  public boolean getRequiresPassword() {
-    return requiresPassword;
-  }
-
-  public boolean getIsOptional() {
-    return isOptional;
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof CredentialGroup)) { return false; }
-    CredentialGroup other = (CredentialGroup) object;
-    return Objects.equal(name, other.name)
-        && Objects.equal(displayName, other.displayName)
-        && Objects.equal(requiresUsername, other.requiresUsername)
-        && Objects.equal(requiresPassword, other.requiresPassword)
-        && Objects.equal(isOptional, other.isOptional)
-        && Objects.equal(mechanisms, other.mechanisms);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(name, displayName, requiresUsername, requiresPassword, isOptional,
-        mechanisms);
-  }
-
-  public boolean isDefault() {
-    return DEFAULT_NAME.equalsIgnoreCase(name);
-  }
-
-  public boolean canUseUlfCredentials() {
-    for (AuthnMechanism mech : mechanisms) {
-      if (mech.canUseUlfCredentials()) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  public static final Predicate<CredentialGroup> DEFAULT_PREDICATE =
-      new Predicate<CredentialGroup>() {
-        public boolean apply(CredentialGroup credentialGroup) {
-          return credentialGroup.isDefault();
-        }
-      };
-
-  public static final Function<Builder, CredentialGroup> BUILD_FUNCTION =
-      new Function<Builder, CredentialGroup>() {
-        public CredentialGroup apply(Builder builder) {
-          return builder.build();
-        }
-      };
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(CredentialGroup.class,
-        ProxyTypeAdapter.make(CredentialGroup.class, LocalProxy.class));
-    builder.registerTypeAdapter(new TypeToken<ImmutableList<AuthnMechanism>>() {}.getType(),
-        TypeAdapters.immutableList());
-  }
-
-  private static final class LocalProxy implements TypeProxy<CredentialGroup> {
-    String name;
-    String displayName;
-    boolean requiresUsername;
-    boolean requiresPassword;
-    boolean isOptional;
-    ImmutableList<AuthnMechanism> mechanisms;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(CredentialGroup credentialGroup) {
-      name = credentialGroup.name;
-      displayName = credentialGroup.displayName;
-      requiresUsername = credentialGroup.requiresUsername;
-      requiresPassword = credentialGroup.requiresPassword;
-      isOptional = credentialGroup.isOptional;
-      mechanisms = credentialGroup.mechanisms;
-    }
-
-    @Override
-    public CredentialGroup build() {
-      return new CredentialGroup(name, displayName, requiresUsername, requiresPassword, isOptional,
-          mechanisms);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/CredentialTransform.java b/src/com/google/enterprise/secmgr/config/CredentialTransform.java
deleted file mode 100644
index 8e580ff..0000000
--- a/src/com/google/enterprise/secmgr/config/CredentialTransform.java
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-/**
- * A model of a particular credential transform implemented by a mechanism.
- * For example, a typical transform accepts some credentials as inputs and
- * verifies them, returning mutually-verified credentials.
- */
-public final class CredentialTransform {
-  private final CredentialTypeSet inputs;
-  private final CredentialTypeSet outputs;
-
-  private CredentialTransform(CredentialTypeSet inputs, CredentialTypeSet outputs) {
-    this.inputs = inputs;
-    this.outputs = outputs;
-  }
-
-  /**
-   * Make a credential transform.
-   *
-   * @param inputs The inputs to the transform.
-   * @param outputs The outputs from the transform.
-   * @return A transform with the given inputs and outputs.
-   */
-  public static CredentialTransform make(CredentialTypeSet inputs, CredentialTypeSet outputs) {
-    return new CredentialTransform(inputs, outputs);
-  }
-
-  /**
-   * @return The inputs to this transform.
-   */
-  public CredentialTypeSet getInputs() {
-    return inputs;
-  }
-
-  /**
-   * @return The outputs from this transform.
-   */
-  public CredentialTypeSet getOutputs() {
-    return outputs;
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/CredentialTypeName.java b/src/com/google/enterprise/secmgr/config/CredentialTypeName.java
deleted file mode 100644
index 6ae5146..0000000
--- a/src/com/google/enterprise/secmgr/config/CredentialTypeName.java
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-/**
- * A set of tokens identifying the possible credential types.  Used by modeling
- * in preference to the classes that implement these types.
- */
-public enum CredentialTypeName {
-  PRINCIPAL, PASSWORD, ALIASES, GROUPS, COOKIES, KERBEROS_TICKET, X509_CERTIFICATE;
-}
diff --git a/src/com/google/enterprise/secmgr/config/CredentialTypeSet.java b/src/com/google/enterprise/secmgr/config/CredentialTypeSet.java
deleted file mode 100644
index 3a10c5a..0000000
--- a/src/com/google/enterprise/secmgr/config/CredentialTypeSet.java
+++ /dev/null
@@ -1,100 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-import java.util.Set;
-
-/**
- * A set of credential types, used as an input to or output from a credential
- * transform.
- */
-public class CredentialTypeSet {
-  private final boolean areVerified;
-  private final ImmutableSet<CredentialTypeName> elements;
-
-  private CredentialTypeSet(boolean areVerified, ImmutableSet<CredentialTypeName> elements) {
-    this.areVerified = areVerified;
-    this.elements = elements;
-  }
-
-  /**
-   * Make a credential-type set.
-   *
-   * @param areVerified True if the represented credentials are verified.
-   * @param elements The credential types that are the elements of this set.
-   * @return A credential-type set with those elements.
-   */
-  public static CredentialTypeSet make(boolean areVerified, Iterable<CredentialTypeName> elements) {
-    return new CredentialTypeSet(areVerified, ImmutableSet.copyOf(elements));
-  }
-
-  /**
-   * @return True if the credentials are mutually verified.
-   */
-  public boolean getAreVerified() {
-    return areVerified;
-  }
-
-  /**
-   * @return An immutable set of the credential types that are the elements of
-   * this set.
-   */
-  public Set<CredentialTypeName> getElements() {
-    return elements;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof CredentialTypeSet)) { return false; }
-    CredentialTypeSet other = (CredentialTypeSet) object;
-    return Objects.equal(getAreVerified(), other.getAreVerified())
-        && Objects.equal(getElements(), other.getElements());
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(getAreVerified(), getElements());
-  }
-
-  public static final CredentialTypeSet NONE =
-      make(false, ImmutableList.<CredentialTypeName>of());
-
-  public static final CredentialTypeSet COOKIES =
-      make(false, ImmutableList.of(CredentialTypeName.COOKIES));
-
-  public static final CredentialTypeSet PRINCIPAL_AND_PASSWORD =
-      make(false, ImmutableList.of(CredentialTypeName.PRINCIPAL, CredentialTypeName.PASSWORD));
-
-  public static final CredentialTypeSet VERIFIED_PRINCIPAL_AND_PASSWORD =
-      make(true, ImmutableList.of(CredentialTypeName.PRINCIPAL, CredentialTypeName.PASSWORD));
-
-  public static final CredentialTypeSet VERIFIED_PRINCIPAL_PASSWORD_AND_GROUPS =
-      make(true, ImmutableList.of(CredentialTypeName.PRINCIPAL, CredentialTypeName.PASSWORD,
-              CredentialTypeName.GROUPS));
-
-  public static final CredentialTypeSet VERIFIED_PRINCIPAL =
-      make(true, ImmutableList.of(CredentialTypeName.PRINCIPAL));
-
-  public static final CredentialTypeSet VERIFIED_ALIASES =
-      make(true, ImmutableList.of(CredentialTypeName.ALIASES));
-
-  public static final CredentialTypeSet VERIFIED_GROUPS =
-      make(true, ImmutableList.of(CredentialTypeName.GROUPS));
-}
diff --git a/src/com/google/enterprise/secmgr/config/FlexAuthorizer.java b/src/com/google/enterprise/secmgr/config/FlexAuthorizer.java
deleted file mode 100644
index 0597a0c..0000000
--- a/src/com/google/enterprise/secmgr/config/FlexAuthorizer.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Interface for Flexible Authorization.
- *
- * This class provides accessors and mutators for the Authz Routing Table and
- * the Authz Rules Table.  Each entry in the routing table is uniquely defined
- * by a UUID.  Each rule in the rule table is uniquely defined by its display
- * name.
- *
- * @author meghna@google.com (Meghna Dhar)
- */
-public interface FlexAuthorizer {
-
-  /**
-   * Add an entry to the routing table.
-   *
-   * @param order The priority order for the entry; the entry will
-   *     be stored at that position, and all subsequent entries have their order
-   *     increased by one.
-   * @param entry The entry to be added.
-   * @throws IllegalArgumentException if the new entry refers to a rule that's
-   *     not in the rule table, or if the order is less than zero or greater
-   *     than the number of entries in the routing table.
-   */
-  public void addToRoutingTable(int order, FlexAuthzRoutingTableEntry entry);
-
-  /**
-   * Add an entry at the end of the routing table.
-   *
-   * @param entry The entry to be added.
-   * @throws IllegalArgumentException if the new entry refers to a rule that's
-   *     not in the rule table.
-   */
-  public void addToRoutingTable(FlexAuthzRoutingTableEntry entry);
-
-  /**
-   * Delete an entry from the routing table.
-   *
-   * @param uuid The UUID of the entry to delete.
-   * @throws IllegalArgumentException if there's no entry in the table with that UUID.
-   */
-  public void deleteFromRoutingTable(UUID uuid);
-
-  /**
-   * Update an entry in the routing table.
-   *
-   * @param order The priority order for the entry; the entry will
-   *     be stored at that position, and all subsequent entries have their order
-   *     increased by one.
-   * @param entry The new entry; must have the same UUID as an existing entry.
-   * @throws IllegalArgumentException if the entry refers to a rule that's not
-   *     in the rule table, or if the entry's UUID doesn't match an existing
-   *     entry.
-   */
-  public void updateRoutingTable(int order, FlexAuthzRoutingTableEntry entry);
-
-  /**
-   * Given a UUID, get the corresponding entry from the routing table.
-   *
-   * @param uuid The UUID to search for.
-   * @return The corresponding entry, or null if there's none.
-   */
-  public FlexAuthzRoutingTableEntry getFromRoutingTable(UUID uuid);
-
-  /**
-   * Given a UUID, get the priority order of the corresponding entry in the routing table.
-   *
-   * @param uuid The UUID to search for.
-   * @return The priority order of the corresponding entry, or -1 if there's none.
-   */
-  public int getRoutingPriorityOrder(UUID uuid);
-
-  /**
-   * Get all the entries in the routing table, in priority order.
-   *
-   * @return An immutable list of the routing-table entries.
-   */
-  public List<FlexAuthzRoutingTableEntry> getAllRoutingTable();
-
-  /**
-   * @return The number of entries in the routing table.
-   */
-  public int getRoutingTableSize();
-
-  /**
-   * Add a new rule to the rule table.
-   *
-   * @param entry The rule to be added.
-   * @throws IllegalArgumentException if there's already a rule of that name in the table.
-   */
-  public void addToRulesTable(FlexAuthzRule entry);
-
-  /**
-   * Delete a rule from the rule table.
-   *
-   * @param displayName The name of the rule to delete.
-   * @throws IllegalStateException if the rule is referred to by a routing-table
-   *     entry, or if there's no rule of that name in the rule table.
-   */
-  public void deleteFromRulesTable(String displayName);
-
-  /**
-   * Update a rule in the rule table.  Also updates all the routing-table
-   * entries that refer to the rule being replaced.
-   *
-   * @param entry The replacement rule.
-   * @throws IllegalArgumentException if there's no rule of that name in the table.
-   */
-  public void updateRulesTable(FlexAuthzRule entry);
-
-  /**
-   * Given a name, get the matching rule from the rule table.
-   *
-   * @param displayName The name to search for.
-   * @return The rule with that name, or null if there's none.
-   */
-  public FlexAuthzRule getFromRulesTable(String displayName);
-
-  /**
-   * Get all the rules in the rule table.
-   *
-   * @return An immutable list of the rules in the table.
-   */
-  public List<FlexAuthzRule> getAllRulesTable();
-
-  /**
-   * Clear the tables.
-   */
-  public void clearTables();
-}
diff --git a/src/com/google/enterprise/secmgr/config/FlexAuthorizerImpl.java b/src/com/google/enterprise/secmgr/config/FlexAuthorizerImpl.java
deleted file mode 100644
index f0414a2..0000000
--- a/src/com/google/enterprise/secmgr/config/FlexAuthorizerImpl.java
+++ /dev/null
@@ -1,296 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.inject.Inject;
-
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-/**
- * A basic implementation of FlexAuthorizer.  This provides the primary logic
- * for everything except serialization.  The routing table is stored as a list
- * and the priority order is the ordering in the list.  Each row has a unique
- * identifier.  The rule table is stored as a map and the key is the display
- * name of the row.
- *
- * @author meghna@google.com (Meghna Dhar)
- */
-public final class FlexAuthorizerImpl implements FlexAuthorizer {
-
-  private static final String ROOT_URL_PATTERN = "/";
-
-  private final Map<String, FlexAuthzRule> ruleTable;
-  private final List<FlexAuthzRoutingTableEntry> routingTable;
-
-  @Inject
-  private FlexAuthorizerImpl() {
-    ruleTable = Maps.newHashMap();
-    routingTable = Lists.newArrayList();
-  }
-
-  @VisibleForTesting
-  FlexAuthorizerImpl(Map<String, FlexAuthzRule> ruleTable,
-      List<FlexAuthzRoutingTableEntry> routingTable) {
-    this.ruleTable = ruleTable;
-    this.routingTable = routingTable;
-  }
-
-  @Override
-  public void addToRoutingTable(int order, FlexAuthzRoutingTableEntry entry) {
-    checkPriorityOrder(order, routingTable.size());
-    checkForMatchingRule(entry.getAuthzRule());
-    routingTable.add(order, entry);
-  }
-
-  @Override
-  public void addToRoutingTable(FlexAuthzRoutingTableEntry entry) {
-    checkForMatchingRule(entry.getAuthzRule());
-    routingTable.add(entry);
-  }
-
-  @Override
-  public void addToRulesTable(FlexAuthzRule rule) {
-    String name = rule.getRowDisplayName();
-    Preconditions.checkArgument(ruleTable.get(name) == null,
-        "Rule already exists: %s", name);
-    ruleTable.put(name, rule);
-  }
-
-  @Override
-  public void clearTables() {
-    routingTable.clear();
-    ruleTable.clear();
-  }
-
-  @Override
-  public void deleteFromRoutingTable(UUID uuid) {
-    Preconditions.checkNotNull(uuid);
-    int index = getRoutingPriorityOrder(uuid);
-    Preconditions.checkArgument(index >= 0, "Entry not found in routing table: %s", uuid);
-    routingTable.remove(index);
-  }
-
-  @Override
-  public void deleteFromRulesTable(String name) {
-    Preconditions.checkNotNull(name);
-    FlexAuthzRule rule = ruleTable.get(name);
-    Preconditions.checkArgument(rule != null, "Rule isn't in table: %s", name);
-    for (FlexAuthzRoutingTableEntry entry : routingTable) {
-      Preconditions.checkState(entry.getAuthzRule() != rule,
-          "Rule '%s' is referred to by one or more routing-table entries: %s",
-          name, entry.getUniqueRowId().toString());
-    }
-    ruleTable.remove(name);
-  }
-
-  @Override
-  public List<FlexAuthzRoutingTableEntry> getAllRoutingTable() {
-    return ImmutableList.copyOf(routingTable);
-  }
-
-  @Override
-  public List<FlexAuthzRule> getAllRulesTable() {
-    return ImmutableList.copyOf(ruleTable.values());
-  }
-
-  @Override
-  public int getRoutingTableSize() {
-    return routingTable.size();
-  }
-
-  @Override
-  public FlexAuthzRoutingTableEntry getFromRoutingTable(UUID uuid) {
-    Preconditions.checkNotNull(uuid);
-    for (FlexAuthzRoutingTableEntry entry : routingTable) {
-      if (uuid.equals(entry.getUniqueRowId())) {
-        return entry;
-      }
-    }
-    return null;
-  }
-
-  @Override
-  public FlexAuthzRule getFromRulesTable(String name) {
-    Preconditions.checkNotNull(name);
-    return ruleTable.get(name);
-  }
-
-  @Override
-  public void updateRoutingTable(int order, FlexAuthzRoutingTableEntry entry) {
-    checkPriorityOrder(order, routingTable.size() - 1);
-    checkForMatchingRule(entry.getAuthzRule());
-    UUID uuid = entry.getUniqueRowId();
-    int oldIndex = getRoutingPriorityOrder(uuid);
-    Preconditions.checkArgument(oldIndex >= 0, "Entry not found in routing table: %s", uuid);
-    // oldIndex is valid in table prior to change; order is where we want the
-    // entry to be after the change.  So do the delete first, then the insert.
-    routingTable.remove(oldIndex);
-    routingTable.add(order, entry);
-  }
-
-  @Override
-  public void updateRulesTable(FlexAuthzRule rule) {
-    String name = rule.getRowDisplayName();
-    FlexAuthzRule oldRule = ruleTable.get(name);
-    Preconditions.checkArgument(oldRule != null, "Rule not in table: %s", name);
-    ruleTable.put(name, rule);
-    // Now update the routing table, replacing the old rule with the new.
-    for (int i = 0; i < routingTable.size(); i += 1) {
-      FlexAuthzRoutingTableEntry entry = routingTable.get(i);
-      if (entry.getAuthzRule() == oldRule) {
-        routingTable.set(i,
-            new FlexAuthzRoutingTableEntry(
-                entry.getUrlPattern(),
-                rule,
-                entry.getUniqueRowId()));
-      }
-    }
-  }
-
-  public int getRoutingPriorityOrder(UUID uuid) {
-    Preconditions.checkNotNull(uuid);
-    int index = 0;
-    for (FlexAuthzRoutingTableEntry entry : routingTable) {
-      if (entry.getUniqueRowId().equals(uuid)) {
-        return index;
-      }
-      index++;
-    }
-    return -1;
-  }
-
-  private void checkPriorityOrder(int order, int limit) {
-    Preconditions.checkArgument(order >= 0 && order <= limit,
-        "Priority order not in valid range: %d", order);
-  }
-
-  private void checkForMatchingRule(FlexAuthzRule rule) {
-    String ruleName = rule.getRowDisplayName();
-    Preconditions.checkArgument(ruleTable.get(ruleName) == rule,
-        "Rule in table doesn't match: %s", ruleName);
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  @Override
-  public synchronized boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof FlexAuthorizerImpl)) { return false; }
-    FlexAuthorizerImpl other = (FlexAuthorizerImpl) object;
-    return Objects.equal(getAllRulesTable(), other.getAllRulesTable())
-        && Objects.equal(getAllRoutingTable(), other.getAllRoutingTable());
-  }
-
-  @Override
-  public synchronized int hashCode() {
-    return Objects.hashCode(getAllRulesTable(), getAllRoutingTable());
-  }
-
-  public static FlexAuthorizer makeDefault() {
-    return makeDefault(null, false);
-  }
-
-  public static FlexAuthorizer makeDefault(String authzServiceUrl, boolean samlUseBatchedRequests) {
-    FlexAuthorizer flexAuthorizer = new FlexAuthorizerImpl();
-    int index = 0;
-    makeDefaultRule(flexAuthorizer, index++, ROOT_URL_PATTERN,
-        AuthzMechanism.CACHE,
-        FlexAuthzRule.EMPTY_AUTHN_ID);
-    makeDefaultRule(flexAuthorizer, index++, ROOT_URL_PATTERN,
-        AuthzMechanism.POLICY,
-        FlexAuthzRule.LEGACY_AUTHN_ID);
-    if (!Strings.isNullOrEmpty(authzServiceUrl)) {
-      makeDefaultRule(flexAuthorizer, index++, ROOT_URL_PATTERN,
-          AuthzMechanism.SAML,
-          FlexAuthzRule.LEGACY_AUTHN_ID,
-          ImmutableMap.of(
-              FlexAuthzRule.ParamName.SAML_ENTITY_ID, FlexAuthzRule.LEGACY_SAML_ENTITY_ID,
-              FlexAuthzRule.ParamName.SAML_USE_BATCHED_REQUESTS,
-              Boolean.toString(samlUseBatchedRequests)));
-    }
-    makeDefaultRule(flexAuthorizer, index++, FlexAuthzRule.LEGACY_CONNECTOR_URL_PATTERN,
-        AuthzMechanism.CONNECTOR,
-        FlexAuthzRule.LEGACY_AUTHN_ID,
-        ImmutableMap.of(
-            FlexAuthzRule.ParamName.CONNECTOR_NAME, FlexAuthzRule.EMPTY_CONNECTOR_NAME));
-    makeDefaultRule(flexAuthorizer, index++, ROOT_URL_PATTERN,
-        AuthzMechanism.HEADREQUEST,
-        FlexAuthzRule.LEGACY_AUTHN_ID);
-    return flexAuthorizer;
-  }
-
-  private static void makeDefaultRule(FlexAuthorizer flexAuthorizer, int index, String urlPattern,
-      AuthzMechanism authzMechType, String authnId,
-      Map<FlexAuthzRule.ParamName, String> mechSpecificParams) {
-    FlexAuthzRule rule
-        = new FlexAuthzRule(authnId, authzMechType, mechSpecificParams, String.valueOf(index),
-            FlexAuthzRule.NO_TIME_LIMIT);
-    flexAuthorizer.addToRulesTable(rule);
-    flexAuthorizer.addToRoutingTable(new FlexAuthzRoutingTableEntry(urlPattern, rule));
-  }
-
-  private static void makeDefaultRule(FlexAuthorizer flexAuthorizer, int index, String urlPattern,
-      AuthzMechanism authzMechType, String authnId) {
-    FlexAuthzRule rule
-        = new FlexAuthzRule(authnId, authzMechType, String.valueOf(index),
-            FlexAuthzRule.NO_TIME_LIMIT);
-    flexAuthorizer.addToRulesTable(rule);
-    flexAuthorizer.addToRoutingTable(new FlexAuthzRoutingTableEntry(urlPattern, rule));
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(FlexAuthorizer.class,
-        ProxyTypeAdapter.make(FlexAuthorizer.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy implements TypeProxy<FlexAuthorizer> {
-    List<FlexAuthzRoutingTableEntry> entries;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(FlexAuthorizer flexAuthorizer) {
-      entries = flexAuthorizer.getAllRoutingTable();
-    }
-
-    @Override
-    public FlexAuthorizer build() {
-      Map<String, FlexAuthzRule> ruleTable = Maps.newHashMap();
-      for (FlexAuthzRoutingTableEntry entry : entries) {
-        FlexAuthzRule rule = entry.getAuthzRule();
-        ruleTable.put(rule.getRowDisplayName(), rule);
-      }
-      return new FlexAuthorizerImpl(ruleTable, entries);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/FlexAuthzRoutingTableEntry.java b/src/com/google/enterprise/secmgr/config/FlexAuthzRoutingTableEntry.java
deleted file mode 100644
index d41700d..0000000
--- a/src/com/google/enterprise/secmgr/config/FlexAuthzRoutingTableEntry.java
+++ /dev/null
@@ -1,148 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.labs.matcher.ParsedUrlPattern;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-
-import java.util.UUID;
-import java.util.regex.Pattern;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * Implementation of the Flexible Authorization Routing Table Row.
- *
- * Each row in the routing table contains
- * Url Pattern - a string which specifies either a single document via a
- * specific URL or a set of documents that share the same pattern,
- * pointer to the Authz Rule and a unique row identifier.
- *
- * @author meghna@google.com (Meghna Dhar)
- *
- */
-public class FlexAuthzRoutingTableEntry {
-  private final String urlPattern;
-  private final FlexAuthzRule authzRule;
-  private final UUID uniqueRowId;
-
-  public static boolean isValidPattern(String patternStr) {
-    if (patternStr.isEmpty()) {
-      return false;
-    }
-    try {
-      ParsedUrlPattern p = new ParsedUrlPattern(patternStr);
-    } catch (IllegalArgumentException e) {
-      return false;
-    }
-
-    String regexpProtocols[] = new String[] { "regexp:", "regexpIgnoreCase:", "regexpCase:" };
-    for (String regexpProtocol : regexpProtocols) {
-      if (patternStr.startsWith(regexpProtocol)) {
-        try {
-          Pattern.compile(patternStr.substring(regexpProtocol.length()));
-        } catch (PatternSyntaxException e) {
-          return false;
-        }
-      }
-    }
-
-    // TODO(???): Introduce addtional validation as ParsedUrlPattern is lax.
-    /* GSA rules on valid URL patterns:
-       http://code.google.com/apis/searchappliance/documentation/50/help_gsa/z01apprules.html */
-
-    return true;
-  }
-
-  public FlexAuthzRoutingTableEntry(String urlPattern, FlexAuthzRule authzRule) {
-    this(urlPattern, authzRule, UUID.randomUUID());
-  }
-
-  public FlexAuthzRoutingTableEntry(String urlPattern, FlexAuthzRule authzRule,
-      UUID uuid) {
-    if (!isValidPattern(urlPattern)) {
-      throw new IllegalArgumentException("invalid pattern: " + urlPattern);
-    }
-    this.urlPattern = urlPattern;
-    this.authzRule = authzRule;
-    this.uniqueRowId = uuid;
-  }
-
-  public String getUrlPattern() {
-    return urlPattern;
-  }
-
-  public FlexAuthzRule getAuthzRule() {
-    return authzRule;
-  }
-
-  public UUID getUniqueRowId(){
-    return uniqueRowId;
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  /**
-   * only intended to be used for testing
-   * Since each time the default config is loaded, there will be a new
-   * uniqueRowId generated, we do not include the uniqueRowId in the
-   * equals method
-   */
-  @Override
-  public synchronized boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof FlexAuthzRoutingTableEntry)) { return false; }
-    FlexAuthzRoutingTableEntry other = (FlexAuthzRoutingTableEntry) object;
-    return Objects.equal(getUrlPattern(), other.getUrlPattern())
-        && Objects.equal(getAuthzRule(), other.getAuthzRule());
-  }
-
-  @Override
-  public synchronized int hashCode() {
-      return Objects.hashCode(getUrlPattern(), getAuthzRule(), getUniqueRowId());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(FlexAuthzRoutingTableEntry.class,
-        ProxyTypeAdapter.make(FlexAuthzRoutingTableEntry.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy implements TypeProxy<FlexAuthzRoutingTableEntry> {
-    String urlPattern;
-    FlexAuthzRule authzRule;
-    UUID uniqueRowId;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(FlexAuthzRoutingTableEntry entry) {
-      urlPattern = entry.getUrlPattern();
-      authzRule = entry.getAuthzRule();
-      uniqueRowId = entry.getUniqueRowId();
-    }
-
-    @Override
-    public FlexAuthzRoutingTableEntry build() {
-      return new FlexAuthzRoutingTableEntry(urlPattern, authzRule, uniqueRowId);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/FlexAuthzRule.java b/src/com/google/enterprise/secmgr/config/FlexAuthzRule.java
deleted file mode 100644
index c3ae80d..0000000
--- a/src/com/google/enterprise/secmgr/config/FlexAuthzRule.java
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-
-import java.util.Collection;
-import java.util.EnumSet;
-import java.util.Map;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * Implementation of the Flexible Authorization Rule.
- *
- * @author meghna@google.com (Meghna Dhar)
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public class FlexAuthzRule {
-
-  /**
-   * Mechanism-specific parameter names.
-   */
-  public static enum ParamName {
-    /**
-     * Indicates a connector-instance name.  This is a required string-valued
-     * parameter.
-     */
-    CONNECTOR_NAME,
-    /**
-     * Indicates the entity ID of a SAML PDP.  This is a required string-valued
-     * parameter.
-     */
-    SAML_ENTITY_ID,
-    /**
-     * Indicates whether to use the "multi-request" authz protocol.  This is a
-     * required boolean-valued parameter.
-     */
-    SAML_USE_BATCHED_REQUESTS,
-  }
-
-  /**
-   * The empty authentication ID, for use with mechanisms like
-   * {@link AuthzMechanism#CACHE} and {@link AuthzMechanism#POLICY}.
-   */
-  public static final String EMPTY_AUTHN_ID = "";
-
-  /**
-   * The legacy authentication ID, for configuration migration.
-   */
-  public static final String LEGACY_AUTHN_ID = "Default";
-
-  /**
-   * The empty connector name, for use with {@link #LEGACY_CONNECTOR_URL_PATTERN}.
-   */
-  public static final String EMPTY_CONNECTOR_NAME = "";
-
-  /**
-   * The legacy connector URL pattern {@code "^googleconnector://"}.
-   */
-  public static final String LEGACY_CONNECTOR_URL_PATTERN = "^googleconnector://";
-
-  /**
-   * The SAML entity ID to use for legacy SAML clients.
-   */
-  public static final String LEGACY_SAML_ENTITY_ID = "http://example.com/legacy-saml-id";
-
-  /**
-   * Timeout value that indicates this rule has no specific time limit.
-   */
-  public static final int NO_TIME_LIMIT = -1;
-
-  private static final ImmutableList<AuthzMechanism> AUTHZ_MECHANISMS =
-      ImmutableList.copyOf(EnumSet.allOf(AuthzMechanism.class));
-
-  @Nonnull private final String authnId;
-  @Nonnull private final AuthzMechanism authzMechType;
-  @Nonnull private final ImmutableMap<ParamName, String> mechSpecificParams;
-  @Nonnull private final String displayName;
-  private final int timeout;
-
-  /**
-   * Constructor for flex authz rules.
-   *
-   * @param authnId The name of a credential group to use for authorization, or
-   *     an empty string to use the "primary verified identity".
-   * @param authzMechType The authorization mechanism type, for example policy
-   *     ACLs, head requests, connector authorization, SAML, etc.
-   * @param mechSpecificParams A map of parameters that are specific to the
-   *     mechanism type.  A null value is equivalent to an empty map.
-   * @param displayName The display name for this rule's row, which can be used
-   *     as a reference in the routing table.
-   * @param timeout  The timeout for this rule, in milliseconds.
-   */
-  public FlexAuthzRule(String authnId, AuthzMechanism authzMechType,
-      Map<ParamName, String> mechSpecificParams, String displayName, int timeout) {
-    Preconditions.checkNotNull(authnId);
-    Preconditions.checkNotNull(authzMechType);
-    Preconditions.checkNotNull(displayName);
-    this.authnId = authnId;
-    this.authzMechType = authzMechType;
-    if (mechSpecificParams != null) {
-      this.mechSpecificParams = ImmutableMap.copyOf(mechSpecificParams);
-    } else {
-      this.mechSpecificParams = ImmutableMap.of();
-    }
-    this.displayName = displayName;
-    this.timeout = timeout;
-  }
-
-  /**
-   * A constructor for flex authz rules with no mechanism-specific parameters.
-   */
-  public FlexAuthzRule(String authnId, AuthzMechanism mechType, String displayName, int timeout) {
-    this(authnId, mechType, null, displayName, timeout);
-  }
-
-  /** A dummy rule to use when only the timeout matters. */
-  public static final FlexAuthzRule UNCONSTRAINED
-      = new FlexAuthzRule(EMPTY_AUTHN_ID, AuthzMechanism.DENY, "", NO_TIME_LIMIT);
-
-  /** A dummy rule to use for fast authorization. */
-  public static final FlexAuthzRule FAST_AUTHORIZATION
-      = new FlexAuthzRule(EMPTY_AUTHN_ID, AuthzMechanism.DENY, "Fast Authorization", NO_TIME_LIMIT);
-
-  /**
-   * @return The authentication identity name for this rule: a credential-group
-   * name, or the empty string to use the "primary verified identity".
-   */
-  @Nonnull
-  public String getAuthnId() {
-    return authnId;
-  }
-
-  /**
-   * @return The authorization mechanism type for this rule.
-   */
-  @Nonnull
-  public AuthzMechanism getAuthzMechType() {
-    return authzMechType;
-  }
-
-  /**
-   * @return A collection of the available mechanism types.
-   */
-  @Nonnull
-  public static Collection<AuthzMechanism> getAuthzMechTypes() {
-    return AUTHZ_MECHANISMS;
-  }
-
-  /**
-   * @return An immutable copy of the mechanism-specific parameters.
-   */
-  @Nonnull
-  public Map<ParamName, String> getMechSpecificParams() {
-    return mechSpecificParams;
-  }
-
-  @Nonnull
-  public String requiredStringParam(ParamName name) {
-    String value = mechSpecificParams.get(name);
-    Preconditions.checkArgument(value != null);
-    return value;
-  }
-
-  @Nonnull
-  public boolean requiredBooleanParam(ParamName name) {
-    return Boolean.valueOf(requiredStringParam(name));
-  }
-
-  /**
-   * @return The display name for this rule's row.
-   */
-  @Nonnull
-  public String getRowDisplayName() {
-    return displayName;
-  }
-
-  /**
-   * @return The timeout for this rule, in milliseconds.
-   */
-  public int getTimeout() {
-    return timeout;
-  }
-
-  public boolean hasTimeout() {
-    return NO_TIME_LIMIT != timeout;
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  @Override
-  public synchronized boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof FlexAuthzRule)) { return false; }
-    FlexAuthzRule other = (FlexAuthzRule) object;
-    return Objects.equal(getAuthnId(), other.getAuthnId())
-        && Objects.equal(getAuthzMechType(), other.getAuthzMechType())
-        && Objects.equal(getMechSpecificParams(), other.getMechSpecificParams())
-        && Objects.equal(getRowDisplayName(), other.getRowDisplayName())
-        && Objects.equal(getTimeout(), other.getTimeout());
-  }
-
-  @Override
-  public synchronized int hashCode() {
-    return Objects.hashCode(getAuthnId(), getAuthzMechType(), getMechSpecificParams(),
-                            getRowDisplayName(), getTimeout());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(FlexAuthzRule.class,
-        ProxyTypeAdapter.make(FlexAuthzRule.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy implements TypeProxy<FlexAuthzRule> {
-    String authnId;
-    AuthzMechanism authzMechType;
-    String connectorName;
-    String samlEntityId;
-    String samlUseBatchedRequests;
-    String displayName;
-    int timeout;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(FlexAuthzRule rule) {
-      authnId = rule.getAuthnId();
-      authzMechType = rule.getAuthzMechType();
-      connectorName = rule.getMechSpecificParams().get(ParamName.CONNECTOR_NAME);
-      samlEntityId = rule.getMechSpecificParams().get(ParamName.SAML_ENTITY_ID);
-      samlUseBatchedRequests
-          = rule.getMechSpecificParams().get(ParamName.SAML_USE_BATCHED_REQUESTS);
-      displayName = rule.getRowDisplayName();
-      timeout = rule.getTimeout();
-    }
-
-    @Override
-    public FlexAuthzRule build() {
-      Map<ParamName, String> mechSpecificParams = Maps.newHashMap();
-      if (connectorName != null) {
-        mechSpecificParams.put(ParamName.CONNECTOR_NAME, connectorName);
-      }
-      if (samlEntityId != null) {
-        mechSpecificParams.put(ParamName.SAML_ENTITY_ID, samlEntityId);
-      }
-      if (samlUseBatchedRequests != null) {
-        mechSpecificParams.put(ParamName.SAML_USE_BATCHED_REQUESTS, samlUseBatchedRequests);
-      }
-      if (mechSpecificParams.isEmpty()) {
-        mechSpecificParams = null;
-      }
-      return new FlexAuthzRule(authnId, authzMechType, mechSpecificParams, displayName, timeout);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/ParamName.java b/src/com/google/enterprise/secmgr/config/ParamName.java
deleted file mode 100644
index c131388..0000000
--- a/src/com/google/enterprise/secmgr/config/ParamName.java
+++ /dev/null
@@ -1,174 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-
-import java.util.Iterator;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * Configuration parameter names, along with their types and default values.
- */
-@Immutable
-public enum ParamName {
-  ACL_GROUPS_FILENAME(String.class, "../../../../conf/acls/acl_groups.enterprise"),
-  ACL_URLS_FILENAME(String.class, "../../../../conf/acls/acl_urls.enterprise"),
-  CERTIFICATE_AUTHORITIES_FILENAME(String.class, "../../../../conf/certs/cacerts.jks"),
-  // whether to check the server certificate during serving time
-  CHECK_SERVER_CERTIFICATE(Boolean.class, Boolean.valueOf(true)),
-  CONNECTOR_MANAGER_INFO(ConnMgrInfo.class,
-      ConnMgrInfo.make(ImmutableSet.<ConnMgrInfo.Entry>of())),
-  DENY_RULES_FILENAME(String.class, "../../../../conf/deny_rules.enterprise"),
-  GLOBAL_BATCH_REQUEST_TIMEOUT(Float.class, Float.valueOf(2.5f)),
-  GLOBAL_SINGLE_REQUEST_TIMEOUT(Float.class, Float.valueOf(5.0f)),
-  LATE_BINDING_ACL(Boolean.class, Boolean.valueOf(false)),
-  SAML_METADATA_FILENAME(String.class, "../../../../conf/saml-metadata.xml"),
-  SERVER_CERTIFICATE_FILENAME(String.class, "../../../../conf/certs/server.jks"),
-  SIGNING_CERTIFICATE_FILENAME(String.class, "/etc/google/certs/server.crt"),
-  SIGNING_KEY_FILENAME(String.class, "/etc/google/certs/server.key"),
-  SLOW_HOST_EMBARGO_PERIOD(Integer.class, Integer.valueOf(600)),
-  SLOW_HOST_NUMBER_OF_TIMEOUTS(Integer.class, Integer.valueOf(100)),
-  SLOW_HOST_SAMPLE_PERIOD(Integer.class, Integer.valueOf(300)),
-  SLOW_HOST_TRACKER_ENABLED(Boolean.class, Boolean.valueOf(false)),
-  SLOW_HOST_TRACKER_SIZE(Integer.class, Integer.valueOf(100)),
-  STUNNEL_PORT(Integer.class, Integer.valueOf(7843)),
-
-  // deprecated params, for backward compatability when reading config
-  AUTHZ_CONFIG_FILENAME(String.class, "../../../../conf/FlexAuthz.xml"),
-  CONNECTOR_MANAGER_URLS(StringSet.class, new StringSet(ImmutableSet.<String>of()));
-
-  private final Class<?> valueClass;
-  private final Object defaultValue;
-
-  private ParamName(Class<?> valueClass, Object defaultValue) {
-    Preconditions.checkNotNull(valueClass);
-    Preconditions.checkArgument(valueClass.isInstance(defaultValue));
-    this.valueClass = valueClass;
-    this.defaultValue = defaultValue;
-  }
-
-  /**
-   * @return The value class for this parameter.
-   */
-  public Class<?> getValueClass() {
-    return valueClass;
-  }
-
-  /**
-   * @return The default value for this parameter.
-   */
-  public Object getDefaultValue() {
-    return defaultValue;
-  }
-
-  /**
-   * Is a given object a valid value for this key?
-   *
-   * @param value The object to check.
-   * @return True only if it would be a valid value.
-   */
-  public boolean isValidValue(Object value) {
-    return valueClass.isInstance(value);
-  }
-
-  /**
-   * Given a string representing a value for this key, converts it to an
-   * object.
-   *
-   * @param value The string to convert.
-   * @param valueClass The class of object to convert it to.
-   * @return The converted value.
-   * @throws IllegalArgumentException if the string can't be converted, or if
-   *     the value class is inappropriate for this parameter.
-   */
-  public <T> T stringToValue(String value, Class<T> valueClass) {
-    Preconditions.checkNotNull(value);
-    Preconditions.checkArgument(valueClass.isAssignableFrom(this.valueClass));
-    if (this.valueClass == String.class) {
-      return valueClass.cast(value);
-    }
-    try {
-      if (this.valueClass == Integer.class) {
-        return valueClass.cast(Integer.valueOf(value));
-      }
-      if (this.valueClass == Float.class) {
-        return valueClass.cast(Float.valueOf(value));
-      }
-    } catch (NumberFormatException e) {
-      throw new IllegalArgumentException(e);
-    }
-    if (this.valueClass == ConnMgrInfo.class) {
-      return valueClass.cast(ConnMgrInfo.valueOf(value));
-    }
-    if (this.valueClass == StringSet.class) {
-      return valueClass.cast(StringSet.valueOf(value));
-    }
-    throw new IllegalStateException("Unknown value class: " + valueClass.getName());
-  }
-
-  private static final class StringSet implements Iterable<String> {
-
-    final ImmutableSet<String> contents;
-
-    StringSet(ImmutableSet<String> contents) {
-      this.contents = ImmutableSet.copyOf(contents);
-    }
-
-    @Override
-    public Iterator<String> iterator() {
-      return contents.iterator();
-    }
-
-    /**
-     * Decodes a string-encoded string set.
-     *
-     * @param string The encoded string set.
-     * @return The decoded string set.
-     */
-    public static StringSet valueOf(String string) {
-      return ConfigSingleton.getGson().fromJson(string, StringSet.class);
-    }
-
-    @Override
-    public boolean equals(Object object) {
-      if (this == object) { return true; }
-      if (!(object instanceof StringSet)) { return false; }
-      StringSet other = (StringSet) object;
-      return Objects.equal(contents, other.contents);
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(contents);
-    }
-
-    @Override
-    public String toString() {
-      return ConfigSingleton.getGson().toJson(this);
-    }
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(new TypeToken<ImmutableSet<String>>() {}.getType(),
-        TypeAdapters.immutableSet());
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/SecurityManagerConfig.java b/src/com/google/enterprise/secmgr/config/SecurityManagerConfig.java
deleted file mode 100644
index e070283..0000000
--- a/src/com/google/enterprise/secmgr/config/SecurityManagerConfig.java
+++ /dev/null
@@ -1,454 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Objects;
-import com.google.common.base.Pair;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.annotations.SerializedName;
-import com.google.gson.reflect.TypeToken;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.Locale;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * A class that holds a complete security manager configuration.
- */
-@ThreadSafe
-public final class SecurityManagerConfig {
-
-  static final int CURRENT_VERSION = 5;
-
-  private final int version;
-  @GuardedBy("this") private ImmutableList<CredentialGroup> credentialGroups;
-  @GuardedBy("this") private ImmutableList<AuthnMechanism> mechanisms;
-  @GuardedBy("this") private ConfigParams params;
-  @GuardedBy("this") private FlexAuthorizer flexAuthorizer;
-
-  private SecurityManagerConfig(int version, ImmutableList<CredentialGroup> credentialGroups,
-      ConfigParams params, FlexAuthorizer flexAuthorizer) {
-    this.version = version;
-    setCredentialGroupsInternal(credentialGroups);
-    this.params = params;
-    this.flexAuthorizer = flexAuthorizer;
-  }
-
-  /**
-   * Set a configuration's credential groups.  The security manager uses this
-   * only for testing.
-   *
-   * @param credentialGroups The new credential groups.
-   * @throws IllegalArgumentException if there's a problem with the argument.
-   */
-  public void setCredentialGroupsInternal(ImmutableList<CredentialGroup> credentialGroups) {
-    ImmutableList.Builder<AuthnMechanism> mechanismsBuilder = ImmutableList.builder();
-    for (CredentialGroup credentialGroup : credentialGroups) {
-      mechanismsBuilder.addAll(credentialGroup.getMechanisms());
-    }
-    ImmutableList<AuthnMechanism> mechanisms = mechanismsBuilder.build();
-    synchronized (this) {
-      this.credentialGroups = credentialGroups;
-      this.mechanisms = mechanisms;
-    }
-  }
-
-  /**
-   * Make a security manager configuration.
-   *
-   * @param credentialGroups The configuration's credential groups.
-   * @param params The configuration's parameters.
-   * @param flexAuthorizer The flex authorization configs
-   * @return A security manager configuration.
-   */
-  public static SecurityManagerConfig make(Iterable<CredentialGroup> credentialGroups,
-      ConfigParams params, FlexAuthorizer flexAuthorizer) {
-    Preconditions.checkArgument(params != null);
-    Preconditions.checkArgument(flexAuthorizer != null);
-    return new SecurityManagerConfig(CURRENT_VERSION, checkCredentialGroups(credentialGroups),
-        params, flexAuthorizer);
-  }
-
-  @VisibleForTesting
-  public static SecurityManagerConfig make(Iterable<CredentialGroup> credentialGroups) {
-    return new SecurityManagerConfig(CURRENT_VERSION, checkCredentialGroups(credentialGroups),
-        ConfigParams.makeDefault(),
-        FlexAuthorizerImpl.makeDefault());
-  }
-
-  static SecurityManagerConfig makeInternal(int version, Iterable<CredentialGroup> credentialGroups,
-      ConfigParams params, FlexAuthorizer flexAuthorizer) {
-    Preconditions.checkArgument(version > 0 && version <= CURRENT_VERSION);
-    return new SecurityManagerConfig(
-        version,
-        checkCredentialGroups(credentialGroups),
-        (params != null) ? params : ConfigParams.makeDefault(),
-        (flexAuthorizer != null) ? flexAuthorizer : FlexAuthorizerImpl.makeDefault());
-  }
-
-  private static ImmutableList<CredentialGroup> checkCredentialGroups(
-      Iterable<CredentialGroup> credentialGroups) {
-    Preconditions.checkNotNull(credentialGroups);
-    ImmutableList<CredentialGroup> copy = ImmutableList.copyOf(credentialGroups);
-    Collection<String> names = Lists.newArrayList();
-    for (CredentialGroup group : copy) {
-      checkConfigName(group.getName(), names);
-      for (AuthnMechanism mech : group.getMechanisms()) {
-        checkConfigName(mech.getName(), names);
-      }
-    }
-    return copy;
-  }
-
-  private static void checkConfigName(String name, Collection<String> names) {
-    if (name != null) {
-      name = name.toLowerCase(Locale.US);
-      Preconditions.checkArgument(!names.contains(name),
-          "Configuration name appears more than once: %s", name);
-      names.add(name);
-    }
-  }
-
-  /**
-   * @return A default security manager configuration.
-   */
-  public static SecurityManagerConfig makeDefault() {
-    return SecurityManagerConfig.make(
-        makeDefaultCredentialGroups(),
-        ConfigParams.makeDefault(),
-        FlexAuthorizerImpl.makeDefault());
-  }
-
-  public static ImmutableList<CredentialGroup> makeDefaultCredentialGroups() {
-    return ImmutableList.of(CredentialGroup.builder().build());
-  }
-
-  /**
-   * @return The configuration's version.
-   */
-  int getVersion() {
-    return version;
-  }
-
-  /**
-   * Gets the credential groups contained in this configuration.
-   *
-   * @return The credential groups as an immutable list.  The order is the same
-   *     as was given when this configuration was created.
-   */
-  public synchronized ImmutableList<CredentialGroup> getCredentialGroups() {
-    return credentialGroups;
-  }
-
-  /**
-   * Set a configuration's credential groups.  The security manager uses this
-   * only for testing.
-   *
-   * @param credentialGroups The new credential groups.
-   * @throws IllegalArgumentException if there's a problem with the argument.
-   */
-  public void setCredentialGroups(Iterable<CredentialGroup> credentialGroups) {
-    setCredentialGroupsInternal(checkCredentialGroups(credentialGroups));
-    ConfigSingleton.setChanged();
-  }
-
-  /**
-   * Gets the authentication mechanisms contained in this configuration.
-   *
-   * @return The mechanisms as an immutable list.  The order is the same as was
-   *     given when this configuration was created.
-   */
-  public synchronized ImmutableList<AuthnMechanism> getMechanisms() {
-    return mechanisms;
-  }
-
-  /**
-   * Gets the credential group for a given mechanism.
-   *
-   * @param mechanism The mechanism to get the credential group for.
-   * @return The credential group for the given mechanism.
-   * @throws IllegalArgumentException if the mechanism isn't contained in this
-   *     configuration.
-   */
-  public CredentialGroup getCredentialGroup(AuthnMechanism mechanism) {
-    for (CredentialGroup credentialGroup : getCredentialGroups()) {
-      if (credentialGroup.getMechanisms().contains(mechanism)) {
-        return credentialGroup;
-      }
-    }
-    throw new IllegalArgumentException("Unknown mechanism: " + mechanism);
-  }
-
-  /**
-   * Gets the credential group with a given name.
-   *
-   * @param name The credential-group name to search for.
-   * @return The credential group with that name.
-   * @throws IllegalArgumentException if there's no credential group with that name.
-   */
-  public CredentialGroup getCredentialGroup(String name) {
-    Preconditions.checkNotNull(name);
-    for (CredentialGroup credentialGroup : getCredentialGroups()) {
-      if (name.equalsIgnoreCase(credentialGroup.getName())) {
-        return credentialGroup;
-      }
-    }
-    throw new IllegalArgumentException("No credential group with this name: " + name);
-  }
-
-  /**
-   * Gets an authority predicate for a given credential group.
-   *
-   * @param credentialGroup A credential group to get the predicate for.
-   * @return The authority predicate for the credential group.
-   * @throws IllegalArgumentException if the credential group isn't contained in
-   *     this configuration.
-   */
-  public Predicate<AuthnAuthority> getAuthorityPredicate(CredentialGroup credentialGroup) {
-    ImmutableSet.Builder<AuthnAuthority> builder = ImmutableSet.builder();
-    builder.add(credentialGroup.getAuthority());
-    for (AuthnMechanism mechanism : credentialGroup.getMechanisms()) {
-      builder.add(mechanism.getAuthority());
-    }
-    return Predicates.in(builder.build());
-  }
-
-  public synchronized FlexAuthorizer getFlexAuthorizer() {
-    return flexAuthorizer;
-  }
-
-  /**
-   * Sets this configurations's flex authorizer.  The security manager uses this
-   * only for testing.
-   */
-  public void setFlexAuthorizer(FlexAuthorizer flexAuthorizer) {
-    synchronized (this) {
-      this.flexAuthorizer = flexAuthorizer;
-    }
-    ConfigSingleton.setChanged();
-  }
-
-  /**
-   * @return The configuration parameters.
-   */
-  public synchronized ConfigParams getParams() {
-    return params;
-  }
-
-  /**
-   * Gets a list of credential group name and mechanism name pair for the mechanism.
-   *
-   * @param mechanismType the authentication mechanism type
-   * @return a list of credential group name and mechanism name pair for the mechanism.
-   */
-  public <T extends AuthnMechanism> List<Pair<String, String>> getMechanism(
-      final Class<T> mechanismType) {
-    List<Pair<String, String>> mechanisms = Lists.newArrayList();
-    for (CredentialGroup group : getCredentialGroups()) {
-      for (AuthnMechanism mech : group.getMechanisms()) {
-        if (mechanismType.isInstance(mech)) {
-          mechanisms.add(Pair.of(group.getName(), mech.getName()));
-        }
-      }
-    }
-    return mechanisms;
-  }
-
-  /**
-   * Checks if the mechanism is configured.
-   *
-   * @param mechanismType the authentication mechanism type
-   * @return true if the mechanism is already configured.
-   */
-  public <T extends AuthnMechanism> boolean hasMechanism(final Class<T> mechanismType) {
-    return !getMechanism(mechanismType).isEmpty();
-  }
-
-  /**
-   * Sets a configuration's parameters.  The security manager uses this only for
-   * testing.
-   *
-   * @param params The new parameters.
-   */
-  public void setParams(ConfigParams params) {
-    Preconditions.checkNotNull(params);
-    synchronized (this) {
-      this.params = params;
-    }
-    ConfigSingleton.setChanged();
-  }
-
-  /**
-   * @return The name of the ACL group rules file, never null or empty.
-   */
-  public String getAclGroupsFilename() {
-    return params.get(ParamName.ACL_GROUPS_FILENAME, String.class);
-  }
-
-  /**
-   * @return The name of the ACL URL rules file, never null or empty.
-   */
-  public String getAclUrlsFilename() {
-    return params.get(ParamName.ACL_URLS_FILENAME, String.class);
-  }
-
-  /**
-   * @return The name of the certificate-authority certificates file, never null
-   *     or empty.
-   */
-  public String getCertificateAuthoritiesFilename() {
-    return params.get(ParamName.CERTIFICATE_AUTHORITIES_FILENAME, String.class);
-  }
-
-  /**
-   * @return The boolean value whether to check the server certificate during
-   *     serving time
-   */
-  public Boolean getCheckServerCertificate() {
-    return params.get(ParamName.CHECK_SERVER_CERTIFICATE, Boolean.class);
-  }
-
-  /**
-   * @return The URLs of the configured connector managers as an immutable set.
-   */
-  public StringSet getConnectorManagerUrls() {
-    return params.get(ParamName.CONNECTOR_MANAGER_URLS, StringSet.class);
-  }
-
-  /**
-   * @return The name of the http deny rules file, never null or empty.
-   */
-  public String getDenyRulesFilename() {
-    return params.get(ParamName.DENY_RULES_FILENAME, String.class);
-  }
-
-  /**
-   * @return The global batch request timeout.
-   */
-  public Float getGlobalBatchRequestTimeout() {
-    return params.get(ParamName.GLOBAL_BATCH_REQUEST_TIMEOUT, Float.class);
-  }
-
-  /**
-   * @return The global single request timeout.
-   */
-  public Float getGlobalSingleRequestTimeout() {
-    return params.get(ParamName.GLOBAL_SINGLE_REQUEST_TIMEOUT, Float.class);
-  }
-
-  /**
-   * @return The name of the SAML metadata configuration file, never null or
-   *     empty.
-   */
-  public String getSamlMetadataFilename() {
-    return params.get(ParamName.SAML_METADATA_FILENAME, String.class);
-  }
-
-  /**
-   * @return The name of the security manager's certificate file, never null or
-   *     empty.
-   */
-  public String getServerCertificateFilename() {
-    return params.get(ParamName.SERVER_CERTIFICATE_FILENAME, String.class);
-  }
-
-  /**
-   * @return The name of the certificate file to be used for signing outgoing
-   *     messages, never null or empty.
-   */
-  public String getSigningCertificateFilename() {
-    return params.get(ParamName.SIGNING_CERTIFICATE_FILENAME, String.class);
-  }
-
-  /**
-   * @return The name of the key file to be used for signing outgoing messages,
-   *     never null or empty.
-   */
-  public String getSigningKeyFilename() {
-    return params.get(ParamName.SIGNING_KEY_FILENAME, String.class);
-  }
-
-  /**
-   * @return The port of the stunnel service that is forwarding to the security manager.
-   */
-  public int getStunnelPort() {
-    return params.get(ParamName.STUNNEL_PORT, Integer.class);
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  @Override
-  public synchronized boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof SecurityManagerConfig)) { return false; }
-    SecurityManagerConfig other = (SecurityManagerConfig) object;
-    return Objects.equal(getVersion(), other.getVersion())
-        && Objects.equal(getCredentialGroups(), other.getCredentialGroups())
-        && Objects.equal(getParams(), other.getParams())
-        && Objects.equal(getFlexAuthorizer(), other.getFlexAuthorizer());
-  }
-
-  @Override
-  public synchronized int hashCode() {
-    return Objects.hashCode(getVersion(), getCredentialGroups(), getParams(), getFlexAuthorizer());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(SecurityManagerConfig.class,
-        ProxyTypeAdapter.make(SecurityManagerConfig.class, LocalProxy.class));
-    builder.registerTypeAdapter(new TypeToken<ImmutableList<CredentialGroup>>() {}.getType(),
-        TypeAdapters.immutableList());
-  }
-
-  private static final class LocalProxy implements TypeProxy<SecurityManagerConfig> {
-    int version;
-    @SerializedName("CGs") ImmutableList<CredentialGroup> credentialGroups;
-    ConfigParams params;
-    @SerializedName("flexAuthz") FlexAuthorizer flexAuthorizer;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(SecurityManagerConfig config) {
-      version = config.getVersion();
-      credentialGroups = config.getCredentialGroups();
-      params = config.getParams();
-      flexAuthorizer = config.getFlexAuthorizer();
-    }
-
-    @Override
-    public SecurityManagerConfig build() {
-      return makeInternal(version, credentialGroups, params, flexAuthorizer);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/config/StringSet.java b/src/com/google/enterprise/secmgr/config/StringSet.java
deleted file mode 100644
index db6bdea..0000000
--- a/src/com/google/enterprise/secmgr/config/StringSet.java
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.config;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableSet;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-
-import java.util.Iterator;
-
-import javax.annotation.concurrent.Immutable;
-
-/**
- * An implementation of Set&lt;String&gt; with a reliable string representation.
- */
-@Immutable
-public final class StringSet implements Iterable<String> {
-
-  private final ImmutableSet<String> contents;
-
-  private StringSet(ImmutableSet<String> contents) {
-    this.contents = contents;
-  }
-
-  /**
-   * Makes a new string set.
-   *
-   * @param contents The contents of the new set.
-   * @return A new set with the given contents.
-   */
-  public static StringSet make(Iterable<String> contents) {
-    return new StringSet(ImmutableSet.copyOf(contents));
-  }
-
-  /**
-   * Makes a new string set.
-   *
-   * @param contents The contents of the new set.
-   * @return A new set with the given contents.
-   */
-  public static StringSet make(String... contents) {
-    return new StringSet(ImmutableSet.copyOf(contents));
-  }
-
-  @Override
-  public Iterator<String> iterator() {
-    return contents.iterator();
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (this == object) { return true; }
-    if (!(object instanceof StringSet)) { return false; }
-    StringSet other = (StringSet) object;
-    return Objects.equal(contents, other.contents);
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(contents);
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-
-  /**
-   * Decodes a string-encoded string set.
-   *
-   * @param string The encoded string set.
-   * @return The decoded string set.
-   */
-  public static StringSet valueOf(String string) {
-    return ConfigSingleton.getGson().fromJson(string, StringSet.class);
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(StringSet.class,
-        ProxyTypeAdapter.make(StringSet.class, LocalProxy.class));
-    builder.registerTypeAdapter(new TypeToken<ImmutableSet<String>>() {}.getType(),
-        TypeAdapters.immutableSet());
-  }
-
-  private static final class LocalProxy implements TypeProxy<StringSet> {
-    ImmutableSet<String> contents;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(StringSet set) {
-      contents = set.contents;
-    }
-
-    @Override
-    public StringSet build() {
-      return make(contents);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/http/ConnectorUtil.java b/src/com/google/enterprise/secmgr/http/ConnectorUtil.java
deleted file mode 100644
index 7ced38b..0000000
--- a/src/com/google/enterprise/secmgr/http/ConnectorUtil.java
+++ /dev/null
@@ -1,278 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.enterprise.secmgr.http;
-
-import static com.google.enterprise.secmgr.common.XmlUtil.findChildElement;
-import static com.google.enterprise.secmgr.common.XmlUtil.getChildElementText;
-import static com.google.enterprise.secmgr.common.XmlUtil.getChildElements;
-import static com.google.enterprise.secmgr.common.XmlUtil.isElementWithQname;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.enterprise.secmgr.common.XmlUtil;
-import com.google.enterprise.secmgr.config.ConfigSingleton;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.ls.LSException;
-import org.w3c.dom.ls.LSSerializer;
-
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.StringWriter;
-import java.net.URL;
-import java.util.Map;
-import java.util.Observable;
-import java.util.Observer;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.xml.namespace.QName;
-
-public final class ConnectorUtil {
-
-  // Don't instantiate.
-  private ConnectorUtil() {
-    throw new UnsupportedOperationException();
-  }
-
-  private static final Logger LOGGER = Logger.getLogger(ConnectorUtil.class.getName());
-
-  private static QName cmname(String localPart) {
-    return new QName(localPart);
-  }
-
-  // All of these QName constants are exposed for testing.
-  public static final QName XML_TAG_ANSWER = cmname("Answer");
-  public static final QName XML_TAG_AUTHN_CREDENTIAL = cmname("Credentials");
-  public static final QName XML_TAG_AUTHN_DOMAIN = cmname("Domain");
-  public static final QName XML_TAG_AUTHN_PASSWORD = cmname("Password");
-  public static final QName XML_TAG_AUTHN_REQUEST = cmname("AuthnRequest");
-  public static final QName XML_TAG_AUTHN_RESPONSE = cmname("AuthnResponse");
-  public static final QName XML_TAG_AUTHN_USERNAME = cmname("Username");
-  public static final QName XML_TAG_AUTHZ_QUERY = cmname("AuthorizationQuery");
-  public static final QName XML_TAG_AUTHZ_RESPONSE = cmname("AuthorizationResponse");
-  public static final QName XML_TAG_CONNECTORS = cmname("Connectors");
-  public static final QName XML_TAG_CONNECTOR_INSTANCE = cmname("ConnectorInstance");
-  public static final QName XML_TAG_CONNECTOR_INSTANCES = cmname("ConnectorInstances");
-  public static final QName XML_TAG_CONNECTOR_NAME = cmname("ConnectorName");
-  public static final QName XML_TAG_CONNECTOR_QUERY = cmname("ConnectorQuery");
-  public static final QName XML_TAG_CONNECTOR_TYPE = cmname("ConnectorType");
-  public static final QName XML_TAG_DECISION = cmname("Decision");
-  public static final QName XML_TAG_FAILURE = cmname("Failure");
-  public static final QName XML_TAG_GROUP = cmname("Group");
-  public static final QName XML_TAG_IDENTITY = cmname("Identity");
-  public static final QName XML_TAG_INFO = cmname("Info");
-  public static final QName XML_TAG_RESOURCE = cmname("Resource");
-  public static final QName XML_TAG_RESPONSE_ROOT = cmname("CmResponse");
-  public static final QName XML_TAG_STATUS_ID = cmname("StatusId");
-  public static final QName XML_TAG_SUCCESS = cmname("Success");
-
-  // The connector name attribute should be lower case, however the
-  // connector manager used this form so we have to change to the current.
-  public static final QName XML_ATTR_CONNECTOR_NAME = cmname("ConnectorName");
-
-  public static final QName XML_ATTR_DOMAIN = cmname("domain");
-  public static final QName XML_ATTR_PASSWORD = cmname("password");
-
-  public static final String CONFIG_XML_DECLARATION = "xml-declaration";
-
-  public static final String DECISION_TEXT_PERMIT = "permit";
-  public static final String DECISION_TEXT_DENY = "deny";
-  public static final String DECISION_TEXT_INDETERMINATE = "indeterminate";
-
-  public static final String CM_AUTHENTICATE_SERVLET_PATH = "/authenticate";
-  public static final String CM_AUTHORIZATION_SERVLET_PATH = "/authorization";
-  public static final String CM_INSTANCE_LIST_SERVLET_PATH = "/getConnectorInstanceList";
-
-  public static final String LOG_RESPONSE_EMPTY_NODE = "Empty node";
-
-  public static final int SUCCESS = 0;
-  public static final int RESPONSE_EMPTY_NODE = 5213;
-  public static final int RESPONSE_NULL_CONNECTOR = 5215;
-  public static final int ERROR_PARSING_XML_REQUEST = 5300;
-
-  @GuardedBy("class") private static Map<String, String> urlMap;
-  @GuardedBy("class") private static boolean isInitialized;
-
-  public static synchronized void initialize() {
-    if (!isInitialized) {
-      ConfigSingleton.getObservable().addObserver(LOCAL_OBSERVER);
-      isInitialized = true;
-    }
-  }
-
-  @VisibleForTesting
-  public static synchronized void initializeForTesting(Map<String, String> urlMap) {
-    ConfigSingleton.getObservable().deleteObserver(LOCAL_OBSERVER);
-    ConnectorUtil.urlMap = urlMap;
-    isInitialized = true;
-  }
-
-  private static final Observer LOCAL_OBSERVER
-      = new Observer() {
-          @Override
-          public void update(Observable observable, Object object) {
-            reinitializeUrlMap();
-          }
-        };
-
-  private static void reinitializeUrlMap() {
-    ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
-    Iterable<String> urls;
-    try {
-      urls = ConfigSingleton.getConnectorManagerUrls();
-    } catch (IOException e) {
-      LOGGER.log(Level.SEVERE, "Unable to get list of connector manager URLs: ", e);
-      return;
-    }
-    for (String url : urls) {
-      Set<String> instances;
-      try {
-        instances = getInstances(url);
-      } catch (IOException e) {
-        LOGGER.log(Level.WARNING, "Unable to read connector instances from " + url + ": ", e);
-        continue;
-      }
-      for (String instance : instances) {
-        builder.put(instance, url);
-      }
-    }
-    synchronized (ConnectorUtil.class) {
-      urlMap = builder.build();
-    }
-  }
-
-  /**
-   * @return An immutable map from connector-instance name to connector-manager URL.
-   */
-  public static synchronized Map<String, String> getUrlMap() {
-    if (urlMap == null) {
-      reinitializeUrlMap();
-    }
-    return urlMap;
-  }
-
-  /**
-   * Gets the connector-manager URL associated with a given connector-instance name.
-   *
-   * @param instanceName The connector instance name to look up.
-   * @return The corresponding connector-manager URL, or null if none.
-   */
-  public static String getInstanceManagerUrl(String instanceName) {
-    return getUrlMap().get(instanceName);
-  }
-
-  /**
-   * Gets the connector-manager URL associated with a given connector-instance name.
-   *
-   * @param instanceName The connector instance name to look up.
-   * @return The corresponding connector-manager URL.
-   * @throws IllegalArgumentException if the URL is unknown.
-   */
-  public static String requireInstanceManagerUrl(String instanceName) {
-    String url = getInstanceManagerUrl(instanceName);
-    Preconditions.checkArgument(url != null);
-    return url;
-  }
-
-  /**
-   * Get a list of connector instances from a connector manager.
-   *
-   * @param managerUrl The URL for the connector manager.
-   * @return An immutable set of the instance names from the connector manager.
-   */
-  private static Set<String> getInstances(String managerUrl)
-      throws IOException {
-    Preconditions.checkNotNull(managerUrl);
-    return parseInstanceListResponse(doExchange(null, managerUrl + CM_INSTANCE_LIST_SERVLET_PATH,
-        -1));
-  }
-
-  private static Set<String> parseInstanceListResponse(Document document) {
-    Element root = document.getDocumentElement();
-    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
-    if (!isElementWithQname(root, XML_TAG_RESPONSE_ROOT)) {
-      LOGGER.warning("Unexpected response from connector manager:" + root);
-      return builder.build();
-    }
-    Element instances = findChildElement(root, XML_TAG_CONNECTOR_INSTANCES, false);
-    if (instances != null) {
-      for (Element instance : getChildElements(instances, XML_TAG_CONNECTOR_INSTANCE)) {
-        builder.add(getChildElementText(instance, XML_TAG_CONNECTOR_NAME, true));
-      }
-    }
-    return builder.build();
-  }
-
-  /**
-   */
-  public static Document doExchange(Document request, String cmUrlString, int timeout)
-      throws IOException {
-    HttpExchange exchange = sendRequest(request, cmUrlString, timeout);
-    Document response;
-    try {
-      response = XmlUtil.getInstance().readXmlDocument(
-          new InputStreamReader(exchange.getResponseEntityAsStream(), "UTF-8"));
-    } finally {
-      exchange.close();
-    }
-    return response;
-  }
-
-  private static HttpExchange sendRequest(Document request, String cmUrlString, int timeout)
-      throws IOException {
-    HttpClientInterface httpClient = HttpClientUtil.getHttpClient();
-    HttpExchange exchange = httpClient.postExchange(new URL(cmUrlString), null);
-    if (timeout >= 0) {
-      exchange.setTimeout(timeout);
-    }
-    try {
-      exchange.setRequestHeader("Content-Type", "text/xml");
-      exchange.setRequestBody(documentToString(request).getBytes("UTF-8"));
-      int status = exchange.exchange();
-      if (status > 300) {
-        throw new IOException("Message exchange returned status: " + status);
-      }
-    } catch (IOException e) {
-      exchange.close();
-      throw e;
-    }
-    return exchange;
-  }
-
-  private static String documentToString(Document document)
-      throws IOException {
-    if (document == null) {
-      return "";
-    }
-    XmlUtil xmlUtil = XmlUtil.getInstance();
-    LSSerializer serializer = xmlUtil.makeSerializer();
-    // Don't generate <?xml ... ?> line.
-    serializer.getDomConfig().setParameter(CONFIG_XML_DECLARATION, false);
-    StringWriter output = new StringWriter();
-    try {
-      XmlUtil.writeXmlDocument(document, serializer, xmlUtil.getLsOutput(output));
-    } catch (LSException e) {
-      throw new IOException(e);
-    }
-    return output.toString();
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/http/HttpClientInterface.java b/src/com/google/enterprise/secmgr/http/HttpClientInterface.java
index b34c8b5..1689938 100644
--- a/src/com/google/enterprise/secmgr/http/HttpClientInterface.java
+++ b/src/com/google/enterprise/secmgr/http/HttpClientInterface.java
@@ -16,7 +16,6 @@
 
 import com.google.common.collect.ListMultimap;
 
-import java.io.IOException;
 import java.net.URL;
 
 import javax.annotation.Nonnull;
@@ -28,22 +27,6 @@
  */
 public interface HttpClientInterface {
   /**
-   * Create a new HTTP HEAD exchange object.
-   *
-   * @param url The URL to send the request to.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange headExchange(@Nonnull URL url);
-
-  /**
-   * Create a new HTTP GET exchange object.
-   *
-   * @param url The URL to send the request to.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange getExchange(@Nonnull URL url);
-
-  /**
    * Create a new HTTP POST exchange object.
    *
    * @param url The URL to send the request to.
@@ -52,79 +35,4 @@
    */
   public HttpExchange postExchange(@Nonnull URL url,
       @Nullable ListMultimap<String, String> parameters);
-
-  /**
-   * Create a new HTTP GET or HEAD exchange object.
-   * The method (GET or HEAD) is determined by the configuration for the URL.
-   *
-   * @param url The URL to send the request to.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange newHttpExchange(@Nonnull URL url);
-
-  /**
-   * A marker type for an object representing an HTTP connection.
-   */
-  public interface Connection {
-
-    /**
-     * Close the connection.  After calling this method, the connection can't
-     * be used for further communication.
-     */
-    public void close() throws IOException;
-  }
-
-  /**
-   * Get a persistent connection for a given URL.
-   * The returned connection may be used multiple times.
-   * Calling this twice returns two different connections.
-   *
-   * @param url A URL specifying where to connect to.
-   * @return A new connection to the specified host.
-   */
-  public Connection getConnection(@Nonnull URL url) throws IOException;
-
-  /**
-   * Create a new HTTP HEAD exchange object.
-   *
-   * @param connection The connection to send the request over.
-   * @param url The URL to send the request to.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange headExchange(@Nullable Connection connection, @Nonnull URL url);
-
-  /**
-   * Create a new HTTP GET exchange object.
-   *
-   * @param connection The connection to send the request over.
-   * @param url The URL to send the request to.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange getExchange(@Nullable Connection connection, @Nonnull URL url);
-
-  /**
-   * Create a new HTTP POST exchange object.
-   *
-   * @param connection The connection to send the request over.
-   * @param url The URL to send the request to.
-   * @param parameters The POST parameters.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange postExchange(@Nullable Connection connection, @Nonnull URL url,
-      @Nullable ListMultimap<String, String> parameters);
-
-  /**
-   * Create a new HTTP GET or HEAD exchange object.
-   * The method (GET or HEAD) is determined by the configuration for the URL.
-   *
-   * @param connection The connection to send the request over.
-   * @param url The URL to send the request to.
-   * @return A new HTTP exchange object.
-   */
-  public HttpExchange newHttpExchange(@Nullable Connection connection, @Nonnull URL url);
-
-  /**
-   * Sets connection timeout and socket timeout.
-   */
-  public void setRequestTimeoutMillis(int millisec);
 }
diff --git a/src/com/google/enterprise/secmgr/http/HttpClientUtil.java b/src/com/google/enterprise/secmgr/http/HttpClientUtil.java
deleted file mode 100644
index 613edb5..0000000
--- a/src/com/google/enterprise/secmgr/http/HttpClientUtil.java
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.http;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
-import com.google.enterprise.secmgr.common.CookieStore;
-import com.google.enterprise.secmgr.common.GCookie;
-import com.google.enterprise.secmgr.common.HttpUtil;
-import com.google.enterprise.secmgr.config.ConfigSingleton;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * Utilities useful throughout the security manager.
- */
-@ThreadSafe
-public class HttpClientUtil {
-
-  // don't instantiate
-  private HttpClientUtil() {
-    throw new UnsupportedOperationException();
-  }
-
-  @GuardedBy("class") private static HttpClientInterface clientOverride = null;
-
-  /**
-   * Get an HTTP client to use when communicating with client servers.
-   *
-   * @return An HTTP client.
-   */
-  public static HttpClientInterface getHttpClient() {
-    synchronized (HttpClientUtil.class) {
-      if (clientOverride != null) {
-        return clientOverride;
-      }
-    }
-    return ConfigSingleton.getInstance(HttpClientInterface.class);
-  }
-
-  /**
-   * Set the HTTP client to use when communicating with client servers.  To be
-   * used by unit tests to override the default transport mechanism.
-   *
-   * @param client An HTTP client.
-   */
-  @VisibleForTesting
-  public static void setHttpClient(HttpClientInterface client) {
-    Preconditions.checkNotNull(client);
-    synchronized (HttpClientUtil.class) {
-      clientOverride = client;
-    }
-  }
-
-  /**
-   * Return the redirect location of an HTTP response.
-   *
-   * @param exchange The HTTP exchange object containing the response.
-   * @return The URL from a <code>Refresh</code> or <code>Location</code>
-   *     header, or null if none such.
-   */
-  public static String getRedirectUrl(HttpExchange exchange) {
-    int status = exchange.getStatusCode();
-    if (HttpUtil.isGoodHttpStatus(status)) {
-      return HttpClientUtil.getRefreshUrl(exchange);
-    }
-    if (status >= 300 && status < 400) {
-      return exchange.getResponseHeaderValue("Location");
-    }
-    return null;
-  }
-
-  /**
-   * Get the relative URL string in Refresh header if exists.
-   * @param exchange The HTTP exchange object.
-   * @return The relative URL string of Refresh header or null
-   *   if none exists
-   */
-  private static String getRefreshUrl(HttpExchange exchange) {
-    String refresh = exchange.getResponseHeaderValue("Refresh");
-    if (refresh != null) {
-      int pos = refresh.indexOf(';');
-      if (pos != -1) {
-        // found a semicolon
-        String timeToRefresh = refresh.substring(0, pos);
-        if ("0".equals(timeToRefresh)) {
-          // only follow this if its an immediate refresh (0 seconds)
-          pos = refresh.indexOf('=');
-          if (pos != -1 && (pos + 1) < refresh.length()) {
-            return refresh.substring(pos + 1);
-          }
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Parses cookies from the headers of an HTTP response.
-   *
-   * @param exchange The exchange to get the response headers from.
-   * @param sessionId A session ID to add to log messages.
-   * @param store A cookie store to which the parsed cookies will be added.
-   */
-  public static void parseHttpResponseCookies(HttpExchange exchange, String sessionId,
-      CookieStore store) {
-    GCookie.parseResponseHeaders(
-        exchange.getResponseHeaderValues(HttpUtil.HTTP_HEADER_SET_COOKIE),
-        HttpUtil.toUri(exchange.getUrl()),
-        sessionId,
-        store);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/http/HttpExchange.java b/src/com/google/enterprise/secmgr/http/HttpExchange.java
index 969ec96..c3b0b29 100644
--- a/src/com/google/enterprise/secmgr/http/HttpExchange.java
+++ b/src/com/google/enterprise/secmgr/http/HttpExchange.java
@@ -15,8 +15,6 @@
 package com.google.enterprise.secmgr.http;
 
 import com.google.common.collect.ListMultimap;
-import com.google.enterprise.secmgr.common.CookieStore;
-import com.google.enterprise.secmgr.common.GCookie;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -123,23 +121,6 @@
   public String getRequestHeaderValue(String headerName);
 
   /**
-   * Adds cookies to this exchange's request.
-   *
-   * @param cookies The cookies to add.
-   */
-  public void addCookies(Iterable<GCookie> cookies);
-
-  /**
-   * Gets this exchange's cookies.  Prior to calling {@link #exchange} this will
-   * return the request cookies; subsequently it will return cookies as modified
-   * by the response.
-   *
-   * @return The exchange's cookie store.
-   */
-  @Nonnull
-  public CookieStore getCookies();
-
-  /**
    * Sets the entity of the request.
    *
    * @param byteArrayRequestEntity The bytes to use as an entity.
diff --git a/src/com/google/enterprise/secmgr/identity/AbstractCredential.java b/src/com/google/enterprise/secmgr/identity/AbstractCredential.java
deleted file mode 100644
index a311a15..0000000
--- a/src/com/google/enterprise/secmgr/identity/AbstractCredential.java
+++ /dev/null
@@ -1,47 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-import com.google.common.base.Predicate;
-import com.google.enterprise.secmgr.config.ConfigSingleton;
-
-/**
- * A base class for all credentials.
- *
- * @see Credential
- */
-public abstract class AbstractCredential implements Credential {
-
-  /**
-   * Get a predicate for a given credential subtype.  This predicate is true
-   * only of credentials of that type.
-   *
-   * @param clazz The class of the credential subtype to test for.
-   * @return The requested predicate.
-   */
-  public static final Predicate<Credential> getTypePredicate(
-      final Class<? extends Credential> clazz) {
-    return new Predicate<Credential>() {
-      public boolean apply(Credential credential) {
-        return clazz.isInstance(credential);
-      }
-    };
-  }
-
-  @Override
-  public String toString() {
-    return ConfigSingleton.getGson().toJson(this);
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/identity/AuthnPrincipal.java b/src/com/google/enterprise/secmgr/identity/AuthnPrincipal.java
deleted file mode 100644
index dbe136a..0000000
--- a/src/com/google/enterprise/secmgr/identity/AuthnPrincipal.java
+++ /dev/null
@@ -1,206 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Strings;
-import com.google.enterprise.secmgr.common.Stringify;
-import com.google.enterprise.secmgr.config.CredentialTypeName;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A credential that contains the user's name and optionally some domain info.
- *
- * A principal may be stored in an identity's credential set.  Doing so doesn't
- * imply that it's verified; that's true only if the identity has a verification
- * that explicitly includes the principal.
- *
- * @see Verification
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class AuthnPrincipal extends AbstractCredential
-    implements java.security.Principal {
-
-  @Nonnull private final String name;
-  @Nullable private final String activeDirectoryDomain;
-
-  private AuthnPrincipal(String name, @Nullable String activeDirectoryDomain) {
-    super();
-    Preconditions.checkNotNull(name);
-    this.name = name;
-    this.activeDirectoryDomain = activeDirectoryDomain;
-  }
-
-  /**
-   * Makes a principal.
-   *
-   * @param name The principal's name; may not be null.
-   * @param activeDirectoryDomain The ActiveDirectory domain name; may be null.
-   * @return A principal with the given components.
-   */
-  @Nonnull
-  public static AuthnPrincipal make(String name, @Nullable String activeDirectoryDomain) {
-    return new AuthnPrincipal(name, activeDirectoryDomain);
-  }
-
-  /**
-   * Makes a principal with no domain.
-   *
-   * @param name The username.
-   * @return A principal with the given username and no domain.
-   */
-  @Nonnull
-  public static AuthnPrincipal make(String name) {
-    return new AuthnPrincipal(name, null);
-  }
-
-  /**
-   * Gets the name associated with this identity.  Usually a "user name" or
-   * "login name".
-   *
-   * @return The identity's name as a string.
-   */
-  @Nonnull
-  public String getName() {
-    return name;
-  }
-
-  /**
-   * Gets the Active Directory Domain name associated with this identity.
-   *
-   * @return The domain name as a string.
-   */
-  @Nullable
-  public String getActiveDirectoryDomain() {
-    return activeDirectoryDomain;
-  }
-
-  @Override
-  public boolean isPublic() {
-    return true;
-  }
-
-  @Override
-  public CredentialTypeName getTypeName() {
-    return CredentialTypeName.PRINCIPAL;
-  }
-
-  @Override
-  public boolean isVerifiable() {
-    return !name.isEmpty();
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof AuthnPrincipal)) { return false; }
-    AuthnPrincipal principal = (AuthnPrincipal) object;
-    return Objects.equal(name, principal.getName())
-        && Objects.equal(activeDirectoryDomain, principal.getActiveDirectoryDomain());
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(name, activeDirectoryDomain);
-  }
-
-  @Override
-  public String toString() {
-    return "{principal: " + Stringify.object(joinUsernameDomain(name, activeDirectoryDomain)) + "}";
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(AuthnPrincipal.class,
-        ProxyTypeAdapter.make(AuthnPrincipal.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy implements TypeProxy<AuthnPrincipal> {
-    String name;
-    String activeDirectoryDomain;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(AuthnPrincipal principal) {
-      name = principal.getName();
-      activeDirectoryDomain = principal.getActiveDirectoryDomain();
-    }
-
-    @Override
-    public AuthnPrincipal build() {
-      return make(name, activeDirectoryDomain);
-    }
-  }
-
-  /**
-   * Parses a string into a principal.
-   *
-   * @param string The combined username/domain string.
-   * @return A principal with the separated username and domain.
-   * @see #parseUsernameDomain
-   */
-  @Nonnull
-  public static AuthnPrincipal parse(String string) {
-    String[] parsed = parseUsernameDomain(string);
-    return make(parsed[0], parsed[1]);
-  }
-
-  /**
-   * Parses a string into a username/domain pair.
-   *
-   * @param string The combined username/domain string.
-   * @return The username and domain strings as an array.
-   */
-  @Nonnull
-  public static String[] parseUsernameDomain(String string) {
-    Preconditions.checkNotNull(string);
-    int slash = string.indexOf("\\");
-    if (slash == -1) {
-      slash = string.indexOf("/");
-    }
-    if (slash >= 0) {
-      return new String[] { string.substring(slash + 1), string.substring(0, slash) };
-    }
-    int atSign = string.indexOf("@");
-    if (atSign >= 0) {
-      return new String[] { string.substring(0, atSign), string.substring(atSign + 1) };
-    }
-    return new String[] { string, null };
-  }
-
-  /**
-   * Joins a username and domain into a string.
-   *
-   * @param username The username.
-   * @param domain The domain, or {@code null} if none.
-   * @return The combined username/domain string.
-   */
-  @Nonnull
-  public static String joinUsernameDomain(String username, @Nullable String domain) {
-    Preconditions.checkNotNull(username);
-    return (Strings.isNullOrEmpty(domain)) ? username : username + "@" + domain;
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/identity/CredPassword.java b/src/com/google/enterprise/secmgr/identity/CredPassword.java
deleted file mode 100644
index ab2de0a..0000000
--- a/src/com/google/enterprise/secmgr/identity/CredPassword.java
+++ /dev/null
@@ -1,119 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.enterprise.secmgr.config.CredentialTypeName;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.annotations.SerializedName;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A credential consisting of a password.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class CredPassword extends AbstractCredential {
-
-  @Nonnull private final String text;
-
-  private CredPassword(String text) {
-    Preconditions.checkNotNull(text);
-    this.text = text;
-  }
-
-  /**
-   * Gets a password credential for a given password text.
-   *
-   * @param text The text of the password.
-   * @return A corresponding password credential.
-   */
-  @Nonnull
-  public static CredPassword make(String text) {
-    return new CredPassword(text);
-  }
-
-  @Override
-  public boolean isPublic() {
-    return false;
-  }
-
-  @Override
-  public CredentialTypeName getTypeName() {
-    return CredentialTypeName.PASSWORD;
-  }
-
-  @Override
-  public boolean isVerifiable() {
-    return !text.isEmpty();
-  }
-
-  /**
-   * Gets the user's password.
-   *
-   * @return The password text.
-   */
-  @Nonnull
-  public String getText() {
-    return text;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof CredPassword)) { return false; }
-    CredPassword credential = (CredPassword) object;
-    return Objects.equal(text, credential.getText());
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(text);
-  }
-
-  @Override
-  public String toString() {
-    return "{password}";
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(CredPassword.class,
-        ProxyTypeAdapter.make(CredPassword.class, LocalProxy.class));
-  }
-
-  private static final class LocalProxy implements TypeProxy<CredPassword> {
-    @SerializedName("password") String text;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(CredPassword password) {
-      text = password.getText();
-    }
-
-    @Override
-    public CredPassword build() {
-      return make(text);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/identity/Credential.java b/src/com/google/enterprise/secmgr/identity/Credential.java
deleted file mode 100644
index b66dba8..0000000
--- a/src/com/google/enterprise/secmgr/identity/Credential.java
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-import com.google.enterprise.secmgr.config.CredentialTypeName;
-
-/**
- * A credential.  Examples of credentials include: username, password, kerberos
- * ticket, X.509 certificate.
- */
-public interface Credential {
-
-  /**
-   * Is it OK for this credential to be shared with others?
-   *
-   * Examples of public credentials include: username, X.509 credential.
-   * Examples of private credentials include: password, private key.
-   *
-   * @return True if the credential is public, false if it's private.
-   */
-  public boolean isPublic();
-
-  /**
-   * @return The name of this credential's type.
-   */
-  public CredentialTypeName getTypeName();
-
-  /**
-   * @return True if the credential is verifiable.
-   */
-  public boolean isVerifiable();
-}
diff --git a/src/com/google/enterprise/secmgr/identity/CredentialModule.java b/src/com/google/enterprise/secmgr/identity/CredentialModule.java
deleted file mode 100644
index 08e7100..0000000
--- a/src/com/google/enterprise/secmgr/identity/CredentialModule.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2011 Google Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.google.enterprise.secmgr.identity;
-
-import com.google.common.collect.ImmutableList;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.gson.GsonBuilder;
-
-/**
- * A module for top-level configuration of this package.
- */
-public final class CredentialModule {
-
-  // Don't instantiate.
-  private CredentialModule() {
-    throw new UnsupportedOperationException();
-  }
-
-  public static void registerTypeAdapters(GsonBuilder builder) {
-    AuthnPrincipal.registerTypeAdapters(builder);
-    CredPassword.registerTypeAdapters(builder);
-    GroupMemberships.registerTypeAdapters(builder);
-    Verification.registerTypeAdapters(builder);
-    builder.registerTypeAdapter(Credential.class,
-        TypeAdapters.dispatch(
-            ImmutableList.<Class<? extends Credential>>of(
-                AuthnPrincipal.class,
-                CredPassword.class,
-                GroupMemberships.class)));
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/identity/GroupMemberships.java b/src/com/google/enterprise/secmgr/identity/GroupMemberships.java
deleted file mode 100644
index 2aa365f..0000000
--- a/src/com/google/enterprise/secmgr/identity/GroupMemberships.java
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2010 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableSet;
-import com.google.enterprise.secmgr.common.Stringify;
-import com.google.enterprise.secmgr.config.CredentialTypeName;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * A credential that contains a set of authentication group memberships
- * (such as a list of LDAP groups) to which the subject belongs.
- *
- * Similar to principals, the presence of a GroupMemberships instance does not
- * imply the credential has been verified; that is true only if the identity
- * has a verification that explicitly includes this GroupMemberships.
- * @see Verification
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class GroupMemberships extends AbstractCredential {
-
-  @Nonnull private final ImmutableSet<String> groups;
-
-  private GroupMemberships(Iterable<String> groups) {
-    super();
-    Preconditions.checkNotNull(groups);
-    this.groups = ImmutableSet.copyOf(groups);
-    Preconditions.checkArgument(!this.groups.isEmpty());
-  }
-
-  /**
-   * Make a groups-membership set.
-   *
-   * @param groups The names of the groups.
-   * @return An instance with the given names.
-   */
-  @Nonnull public static GroupMemberships make(Iterable<String> groups) {
-    return new GroupMemberships(groups);
-  }
-
-  /**
-   * Gets a set of the contained group names.
-   *
-   * @return The group's names as an immutable set of strings.
-   */
-  @Nonnull
-  public ImmutableSet<String> getGroups() {
-    return groups;
-  }
-
-  @Override
-  public boolean isPublic() {
-    return true;
-  }
-
-  @Override
-  public CredentialTypeName getTypeName() {
-    return CredentialTypeName.GROUPS;
-  }
-
-  @Override
-  public boolean isVerifiable() {
-    return true;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof GroupMemberships)) { return false; }
-    GroupMemberships g = (GroupMemberships) object;
-    return Objects.equal(groups, g.getGroups());
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(groups);
-  }
-
-  @Override
-  public String toString() {
-    return "{groups: " + Stringify.objects(groups) + "}";
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(GroupMemberships.class,
-        ProxyTypeAdapter.make(GroupMemberships.class, LocalProxy.class));
-    builder.registerTypeAdapter(new TypeToken<ImmutableSet<String>>() {}.getType(),
-        TypeAdapters.immutableSet());
-  }
-
-  private static final class LocalProxy implements TypeProxy<GroupMemberships> {
-    ImmutableSet<String> groups;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(GroupMemberships credential) {
-      groups = credential.getGroups();
-    }
-
-    @Override
-    public GroupMemberships build() {
-      return make(groups);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/identity/Verification.java b/src/com/google/enterprise/secmgr/identity/Verification.java
deleted file mode 100644
index b070ad8..0000000
--- a/src/com/google/enterprise/secmgr/identity/Verification.java
+++ /dev/null
@@ -1,705 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.base.Predicate;
-import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.enterprise.secmgr.common.SecurityManagerUtil;
-import com.google.enterprise.secmgr.common.Stringify;
-import com.google.enterprise.secmgr.json.ProxyTypeAdapter;
-import com.google.enterprise.secmgr.json.TypeAdapters;
-import com.google.enterprise.secmgr.json.TypeProxy;
-import com.google.gson.GsonBuilder;
-import com.google.gson.reflect.TypeToken;
-
-import org.joda.time.DateTimeUtils;
-import org.joda.time.format.DateTimeFormatter;
-import org.joda.time.format.ISODateTimeFormat;
-
-import java.util.Arrays;
-import java.util.Collection;
-
-import javax.annotation.CheckReturnValue;
-import javax.annotation.Nonnegative;
-import javax.annotation.Nonnull;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
-/**
- * The structure that holds results from credential verification.
- */
-@Immutable
-@ParametersAreNonnullByDefault
-public final class Verification {
-
-  /**
-   * A value for a verification expiration time that means the verification
-   * doesn't expire.
-   */
-  public static final long NEVER_EXPIRES = -1;
-
-  /**
-   * A value for a verification expiration time that means the verification
-   * expires when the current servlet request is finished.
-   */
-  public static final long EXPIRES_AFTER_REQUEST = -2;
-
-  /**
-   * Used internally to limit values accepted when making a verification.
-   */
-  public static final long MINIMUM_EXPIRATION_VALUE = -2;
-
-  @Nonnull private final VerificationStatus status;
-  private final long expirationTime;
-  @Nonnull private final ImmutableSet<Credential> credentials;
-
-  private Verification(VerificationStatus status, long expirationTime,
-      Iterable<? extends Credential> credentials) {
-    Preconditions.checkNotNull(status);
-    Preconditions.checkArgument(expirationTime >= MINIMUM_EXPIRATION_VALUE);
-    Preconditions.checkNotNull(credentials);
-    this.status = status;
-    this.expirationTime = expirationTime;
-    this.credentials = ImmutableSet.copyOf(credentials);
-  }
-
-  /**
-   * Gets a verification object with VERIFIED status and given credentials.
-   *
-   * @param expirationTime The expiration time of this verification.
-   * @param credentials The credentials that the status applies to.
-   * @return A verification with the given components.
-   */
-  public static Verification verified(long expirationTime,
-      Iterable<? extends Credential> credentials) {
-    return new Verification(VerificationStatus.VERIFIED, expirationTime, credentials);
-  }
-
-  /**
-   * Gets a verification object with VERIFIED status and given credentials.
-   *
-   * @param expirationTime The expiration time of this verification.
-   * @param credentials The credentials that the status applies to.
-   * @return A verification with the given components.
-   */
-  public static Verification verified(long expirationTime, Credential... credentials) {
-    return verified(expirationTime, Arrays.asList(credentials));
-  }
-
-  /**
-   * Gets a verification object with REFUTED status and given credentials.
-   *
-   * @param credentials The credentials that the status applies to.
-   * @return A verification with the given components.
-   */
-  public static Verification refuted(Iterable<? extends Credential> credentials) {
-    return new Verification(VerificationStatus.REFUTED, EXPIRES_AFTER_REQUEST, credentials);
-  }
-
-  /**
-   * Gets a verification object with REFUTED status and no credentials.
-   *
-   * @return A verification with the given components.
-   */
-  public static Verification refuted() {
-    return refuted(ImmutableSet.<Credential>of());
-  }
-
-  @VisibleForTesting
-  public static Verification make(VerificationStatus status, long expirationTime,
-      Credential... credentials) {
-    return new Verification(status, expirationTime, Arrays.asList(credentials));
-  }
-
-  /**
-   * Gets the status of this verification.
-   *
-   * @return The verification's status.
-   */
-  @Nonnull
-  public VerificationStatus getStatus() {
-    return status;
-  }
-
-  /**
-   * Are the credentials valid?
-   *
-   * @return True if the credentials were verified and found valid.
-   */
-  public boolean isVerified() {
-    return status == VerificationStatus.VERIFIED;
-  }
-
-  /**
-   * Are the credentials invalid?
-   *
-   * @return True if the credentials were verified and found invalid.
-   */
-  public boolean isRefuted() {
-    return status == VerificationStatus.REFUTED;
-  }
-
-  /**
-   * Is the verification status indeterminate?
-   *
-   * @return True if the credentials were verified with indeterminate result.
-   */
-  public boolean isIndeterminate() {
-    return status == VerificationStatus.INDETERMINATE;
-  }
-
-  /**
-   * Gets the expiration time for this verification.  Positive is a time
-   * comparable to {@link System#currentTimeMillis}, zero means "already
-   * expired", negative means "never expires".
-   *
-   * @return The expiration time.
-   */
-  public long getExpirationTime() {
-    return expirationTime;
-  }
-
-  /**
-   * Has the verification expired based on the given time?
-   *
-   * @param now The reference time.
-   * @return True if the verification has expired.
-   */
-  public boolean hasExpired(long now) {
-    return expirationTime >= 0
-        && !SecurityManagerUtil.isRemoteOnOrAfterTimeValid(expirationTime, now);
-  }
-
-  /**
-   * Compares the expiration time of this verification with that of a given
-   * verification.  The result is a positive number if the expiration time of
-   * this verification is later than that of the other; a negative number if
-   * this time is earlier than that of the other; or zero if they are equal.
-   *
-   * @param other The verification to compare to.
-   * @return The comparison result.
-   */
-  @CheckReturnValue
-  public int compareExpirationTimes(Verification other) {
-    return compareExpirationTimes(getExpirationTime(), other.getExpirationTime());
-  }
-
-  /**
-   * Compares two expiration times.
-   *
-   * @param t1 The first expiration time.
-   * @param t2 The second expiration time.
-   * @return A negative number if {@code t1<t2}, a positive number if
-   *     {@code t1>t2}, or zero if {@code t1==t2}.
-   * @throws IllegalArgumentException if either of the arguments is not
-   *     recognized as an expiration time.
-   */
-  @CheckReturnValue
-  public static int compareExpirationTimes(long t1, long t2) {
-    Preconditions.checkArgument(t1 >= MINIMUM_EXPIRATION_VALUE);
-    Preconditions.checkArgument(t2 >= MINIMUM_EXPIRATION_VALUE);
-    if (t1 == t2) { return 0; }
-    if (t1 == NEVER_EXPIRES) { return 1; }
-    if (t2 == NEVER_EXPIRES) { return -1; }
-    if (t1 == 0) { return -1; }
-    if (t2 == 0) { return 1; }
-    if (t1 == EXPIRES_AFTER_REQUEST) { return -1; }
-    if (t2 == EXPIRES_AFTER_REQUEST) { return 1; }
-    return (t1 > t2) ? 1 : -1;
-  }
-
-  /**
-   * Gets the minimum expiration time for some given verifications.  Ignores any
-   * verifications that don't satisfy {@link #isVerified}.
-   *
-   * @param verifications Some verifications to test.
-   * @return The earliest expiration time for those verifications.  Returns
-   *     {@link #NEVER_EXPIRES} if there are no verifications.
-   */
-  @CheckReturnValue
-  public static long minimumExpirationTime(Iterable<Verification> verifications) {
-    long expirationTime = NEVER_EXPIRES;
-    for (Verification verification : verifications) {
-      if (verification.isVerified()
-          && compareExpirationTimes(verification.getExpirationTime(), expirationTime) < 0) {
-        expirationTime = verification.getExpirationTime();
-      }
-    }
-    return expirationTime;
-  }
-
-  /**
-   * Gets the maximum expiration time for some given verifications.  Ignores any
-   * verifications that don't satisfy {@link #isVerified}.
-   *
-   * @param verifications Some verifications to test.
-   * @return The latest expiration time for those verifications.  Returns
-   *     {@code 0} if there are no verifications.
-   */
-  @CheckReturnValue
-  public static long maximumExpirationTime(Iterable<Verification> verifications) {
-    long expirationTime = 0;
-    for (Verification verification : verifications) {
-      if (verification.isVerified()
-          && compareExpirationTimes(verification.getExpirationTime(), expirationTime) > 0) {
-        expirationTime = verification.getExpirationTime();
-      }
-    }
-    return expirationTime;
-  }
-
-  /**
-   * Gets the credentials that were verified.
-   *
-   * @return An immutable set of the credentials that underwent verification.
-   */
-  @Nonnull
-  public ImmutableSet<Credential> getCredentials() {
-    return credentials;
-  }
-
-  /**
-   * Does this verification contain a given credential?
-   *
-   * @param credential A credential to test for.
-   * @return True if the given credential is contained.
-   */
-  public boolean containsCredential(Credential credential) {
-    for (Credential v : credentials) {
-      if (v.equals(credential)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Does this verification contain all of some given credentials?
-   *
-   * @param credentials Some credentials to test for.
-   * @return True if all of the given credentials are contained.
-   */
-  public boolean containsAllCredentials(Iterable<? extends Credential> credentials) {
-    for (Credential credential : credentials) {
-      if (!containsCredential(credential)) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  /**
-   * Does this verification contain any of some given credentials?
-   *
-   * @param credentials Some credentials to test for.
-   * @return True if any of the given credentials are contained.
-   */
-  public boolean containsAnyCredential(Iterable<? extends Credential> credentials) {
-    for (Credential credential : credentials) {
-      if (containsCredential(credential)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @Override
-  public boolean equals(Object object) {
-    if (object == this) { return true; }
-    if (!(object instanceof Verification)) { return false; }
-    Verification verification = (Verification) object;
-    return Objects.equal(status, verification.getStatus())
-        && Objects.equal(credentials, verification.getCredentials());
-  }
-
-  @Override
-  public int hashCode() {
-    return Objects.hashCode(status, credentials);
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder builder = new StringBuilder();
-    builder.append("{Verification: status=");
-    builder.append(status);
-    builder.append("; ");
-    if (expirationTime == NEVER_EXPIRES) {
-      builder.append("never expires");
-    } else if (expirationTime == EXPIRES_AFTER_REQUEST) {
-      builder.append("expires after request");
-    } else {
-      builder.append("expires at ");
-      builder.append(ISO8601_FORMAT.print(expirationTime));
-    }
-    if (!credentials.isEmpty()) {
-      builder.append("; credentials ");
-      builder.append(Stringify.objects(credentials));
-    }
-    builder.append("}");
-    return builder.toString();
-  }
-
-  private static final DateTimeFormatter ISO8601_FORMAT = ISODateTimeFormat.dateTime();
-
-  /**
-   * Gets a predicate that compares a verification's status to a given value.
-   *
-   * @param status A status to test for.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getStatusPredicate(VerificationStatus status) {
-    return Predicates.compose(Predicates.equalTo(status), GET_STATUS_FUNCTION);
-  }
-
-  private static final Function<Verification, VerificationStatus> GET_STATUS_FUNCTION =
-      new Function<Verification, VerificationStatus>() {
-        @Override
-        public VerificationStatus apply(Verification v) {
-          return v.getStatus();
-        }
-      };
-
-  /**
-   * Gets a predicate that tests whether a given verification has status
-   * {@link VerificationStatus#VERIFIED}.
-   *
-   * @return The predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> isVerifiedPredicate() {
-    return IS_VERIFIED_PREDICATE;
-  }
-
-  private static final Predicate<Verification> IS_VERIFIED_PREDICATE
-      = getStatusPredicate(VerificationStatus.VERIFIED);
-
-  /**
-   * Gets a predicate that tests whether a given verification has status
-   * {@link VerificationStatus#REFUTED}.
-   *
-   * @return The predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> isRefutedPredicate() {
-    return IS_REFUTED_PREDICATE;
-  }
-
-  private static final Predicate<Verification> IS_REFUTED_PREDICATE
-      = getStatusPredicate(VerificationStatus.REFUTED);
-
-  /**
-   * Gets a predicate that tests whether a verification is expired
-   *
-   * @param time The reference time for the expiration.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getExpirationPredicate(final long time) {
-    return new Predicate<Verification>() {
-      @Override
-      public boolean apply(Verification v) {
-        return v.hasExpired(time);
-      }
-    };
-  }
-
-  /**
-   * Gets a predicate that tests whether a verification should expire after the
-   * current request.
-   *
-   * @return The predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getRequestExpirationPredicate() {
-    return REQUEST_EXPIRATION_PREDICATE;
-  }
-
-  private static final Function<Verification, Long> GET_EXPIRATION_TIME_FUNCTION =
-      new Function<Verification, Long>() {
-        @Override
-        public Long apply(Verification v) {
-          return v.getExpirationTime();
-        }
-      };
-
-  private static final Predicate<Verification> REQUEST_EXPIRATION_PREDICATE =
-      Predicates.compose(Predicates.equalTo(EXPIRES_AFTER_REQUEST), GET_EXPIRATION_TIME_FUNCTION);
-
-  /**
-   * Gets a predicate that invokes the {@link #containsCredential} method on a
-   * given verification.
-   *
-   * @param credential The credential to test for.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getContainsCredentialPredicate(
-      final Credential credential) {
-    Preconditions.checkNotNull(credential);
-    return new Predicate<Verification>() {
-      @Override
-      public boolean apply(Verification verification) {
-        return verification.containsCredential(credential);
-      }
-    };
-  }
-
-  /**
-   * Gets a predicate that invokes the {@link #containsAllCredentials} method on
-   * a given verification.
-   *
-   * @param credentials The credentials to test for.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getContainsAllCredentialsPredicate(
-      final Iterable<? extends Credential> credentials) {
-    Preconditions.checkNotNull(credentials);
-    return new Predicate<Verification>() {
-      @Override
-      public boolean apply(Verification verification) {
-        return verification.containsAllCredentials(credentials);
-      }
-    };
-  }
-
-  /**
-   * Gets a predicate that invokes the {@link #containsAllCredentials} method on
-   * a given verification.
-   *
-   * @param credentials The credentials to test for.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getContainsAllCredentialsPredicate(
-      Credential... credentials) {
-    return getContainsAllCredentialsPredicate(Arrays.asList(credentials));
-  }
-
-  /**
-   * Gets a predicate that invokes the {@link #containsAnyCredential} method on
-   * a given verification.
-   *
-   * @param credentials The credentials to test for.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getContainsAnyCredentialPredicate(
-      final Iterable<? extends Credential> credentials) {
-    return new Predicate<Verification>() {
-      public boolean apply(Verification v) {
-        return v.containsAnyCredential(credentials);
-      }
-    };
-  }
-
-  /**
-   * Gets a predicate that invokes the {@link #containsAnyCredential} method on
-   * a given verification.
-   *
-   * @param credentials The credentials to test for.
-   * @return The corresponding predicate.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Predicate<Verification> getContainsAnyCredentialPredicate(
-      Credential... credentials) {
-    return getContainsAnyCredentialPredicate(Arrays.asList(credentials));
-  }
-
-  /**
-   * Determines the verification status from a set of verifications.
-   *
-   * @param verifications The set of verifications to check.
-   * @return The aggregate status of the verifications.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static VerificationStatus getStatus(Iterable<Verification> verifications) {
-    VerificationStatus result = VerificationStatus.INDETERMINATE;
-    for (Verification verification : verifications) {
-      if (verification.isRefuted()) {
-        return VerificationStatus.REFUTED;
-      }
-      if (verification.isVerified()) {
-        result = VerificationStatus.VERIFIED;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Determines the joint verification status for some given credentials from a
-   * set of verifications.
-   *
-   * @param verifications The set of verifications to check.
-   * @param credentials The set of credentials to look for.
-   * @return The joint verification status of the relevant verifications.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static VerificationStatus getStatus(Iterable<Verification> verifications,
-      Iterable<? extends Credential> credentials) {
-    return getStatus(
-        Iterables.filter(verifications,
-            getContainsAllCredentialsPredicate(credentials)));
-  }
-
-  /**
-   * Determines whether one of a set of verifications has VERIFIED state.
-   *
-   * @param verifications The set of verifications to check.
-   * @return True if there's at least one VERIFIED element in the set.
-   */
-  public static boolean isVerified(Iterable<Verification> verifications) {
-    return getStatus(verifications) == VerificationStatus.VERIFIED;
-  }
-
-  /**
-   * Determines whether one of a set of verifications has REFUTED state.
-   *
-   * @param verifications The set of verifications to check.
-   * @return True if there's at least one REFUTED element in the set.
-   */
-  public static boolean isRefuted(Iterable<Verification> verifications) {
-    return getStatus(verifications) == VerificationStatus.REFUTED;
-  }
-
-  /**
-   * Determines whether none of a set of verifications has VERIFIED or REFUTED
-   * state.
-   *
-   * @param verifications The set of verifications to check.
-   * @return False if there's at least one VERIFIED or REFUTED element in the
-   *     set.
-   */
-  public static boolean isIndeterminate(Iterable<Verification> verifications) {
-    return getStatus(verifications) == VerificationStatus.INDETERMINATE;
-  }
-
-  /**
-   * Determines whether one of a set of verifications has VERIFIED state and
-   * contains all of the given credentials.
-   *
-   * @param verifications The set of verifications to check.
-   * @param credentials The set of credentials to look for.
-   * @return True if there's at least one VERIFIED element in the containing all
-   *     of the credentials.
-   */
-  public static boolean isVerified(Iterable<Verification> verifications,
-      Iterable<Credential> credentials) {
-    return getStatus(verifications, credentials) == VerificationStatus.VERIFIED;
-  }
-
-  /**
-   * Determines whether one of a set of verifications has REFUTED state and
-   * contains all of the given credentials.
-   *
-   * @param verifications The set of verifications to check.
-   * @param credentials The set of credentials to look for.
-   * @return True if there's at least one REFUTED element in the containing all
-   *     of the credentials.
-   */
-  public static boolean isRefuted(Iterable<Verification> verifications,
-      Iterable<Credential> credentials) {
-    return getStatus(verifications, credentials) == VerificationStatus.REFUTED;
-  }
-
-  /**
-   * Gets the newest of a set of verifications; in other words, the verification
-   * with the latest expiration time.
-   *
-   * @param verifications The verifications to test.
-   * @return The newest of the given verifications, or {@code null} if the given
-   *     set is empty.
-   */
-  @CheckReturnValue
-  @Nonnull
-  public static Verification newestOf(Iterable<Verification> verifications) {
-    Verification result = null;
-    for (Verification verification : verifications) {
-      if (result == null || verification.compareExpirationTimes(result) > 0) {
-        result = verification;
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Removes any expired verifications from a given collection.
-   *
-   * @param verifications A collection of verifications to process.
-   * @param timeStamp A reference time for determining expiration.
-   */
-  public static void expireVerifications(Collection<Verification> verifications,
-      @Nonnegative long timeStamp) {
-    Iterables.removeIf(verifications, getExpirationPredicate(timeStamp));
-  }
-
-  /**
-   * Removes any expired verifications from a given collection.  Uses the
-   * current time as a reference.
-   *
-   * @param verifications A collection of verifications to process.
-   */
-  public static void expireVerifications(Collection<Verification> verifications) {
-    expireVerifications(verifications, DateTimeUtils.currentTimeMillis());
-  }
-
-  static void registerTypeAdapters(GsonBuilder builder) {
-    builder.registerTypeAdapter(Verification.class,
-        ProxyTypeAdapter.make(Verification.class, LocalProxy.class));
-    builder.registerTypeAdapter(new TypeToken<ImmutableSet<Credential>>() {}.getType(),
-        TypeAdapters.immutableSet());
-  }
-
-  private static final class LocalProxy implements TypeProxy<Verification> {
-    VerificationStatus status;
-    long expirationTime;
-    ImmutableSet<Credential> credentials;
-
-    @SuppressWarnings("unused")
-    LocalProxy() {
-    }
-
-    @SuppressWarnings("unused")
-    LocalProxy(Verification verification) {
-      status = verification.getStatus();
-      expirationTime = verification.getExpirationTime();
-      credentials = verification.getCredentials();
-    }
-
-    @Override
-    public Verification build() {
-      return new Verification(status, expirationTime, credentials);
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/identity/VerificationStatus.java b/src/com/google/enterprise/secmgr/identity/VerificationStatus.java
deleted file mode 100644
index 4ddaf2c..0000000
--- a/src/com/google/enterprise/secmgr/identity/VerificationStatus.java
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.identity;
-
-/**
- * The status code attached to a {@link Verification} indicating the disposition
- * of the verification.
- */
-public enum VerificationStatus {
-  VERIFIED,       // recognized by IdP
-  REFUTED,        // unrecognized by IdP
-  INDETERMINATE   // unable to verify
-}
diff --git a/src/com/google/enterprise/secmgr/modules/SamlClient.java b/src/com/google/enterprise/secmgr/modules/SamlClient.java
index 85ebae5..28880e2 100644
--- a/src/com/google/enterprise/secmgr/modules/SamlClient.java
+++ b/src/com/google/enterprise/secmgr/modules/SamlClient.java
@@ -14,7 +14,6 @@
 
 package com.google.enterprise.secmgr.modules;
 
-import static com.google.enterprise.secmgr.saml.OpenSamlUtil.getMetadataSignaturePolicyRule;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.initializeLocalEntity;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.initializePeerEntity;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.makeAction;
@@ -22,9 +21,7 @@
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.makeAuthnRequest;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.makeAuthzDecisionQuery;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.makeSamlMessageContext;
-import static com.google.enterprise.secmgr.saml.OpenSamlUtil.makeStaticSecurityPolicyResolver;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.makeSubject;
-import static com.google.enterprise.secmgr.saml.OpenSamlUtil.peerSupportsSignatureVerification;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.runDecoder;
 import static com.google.enterprise.secmgr.saml.OpenSamlUtil.runEncoder;
 import static org.opensaml.common.xml.SAMLConstants.SAML20P_NS;
@@ -33,24 +30,19 @@
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.Maps;
-//import com.google.enterprise.secmgr.authncontroller.AuthnSession;
 import com.google.enterprise.secmgr.common.AuthzStatus;
-import com.google.enterprise.secmgr.common.HttpUtil;
-//import com.google.enterprise.secmgr.common.ServletBase;
 import com.google.enterprise.secmgr.http.HttpClientInterface;
 import com.google.enterprise.secmgr.http.HttpExchange;
 import com.google.enterprise.secmgr.saml.HTTPSOAP11MultiContextDecoder;
 import com.google.enterprise.secmgr.saml.HTTPSOAP11MultiContextEncoder;
 import com.google.enterprise.secmgr.saml.HttpExchangeToInTransport;
 import com.google.enterprise.secmgr.saml.HttpExchangeToOutTransport;
-import com.google.enterprise.secmgr.saml.MetadataEditor;
 import com.google.enterprise.secmgr.saml.SamlLogUtil;
 
 import org.joda.time.DateTime;
 import org.opensaml.common.SAMLObject;
 import org.opensaml.common.binding.SAMLMessageContext;
 import org.opensaml.common.xml.SAMLConstants;
-import org.opensaml.saml2.binding.decoding.HTTPPostDecoder;
 import org.opensaml.saml2.binding.decoding.HTTPSOAP11Decoder;
 import org.opensaml.saml2.binding.encoding.HTTPRedirectDeflateEncoder;
 import org.opensaml.saml2.binding.encoding.HTTPSOAP11Encoder;
@@ -75,16 +67,13 @@
 import org.opensaml.util.URLBuilder;
 import org.opensaml.ws.message.encoder.MessageEncoder;
 import org.opensaml.ws.message.encoder.MessageEncodingException;
-import org.opensaml.ws.security.provider.MandatoryAuthenticatedMessageRule;
-import org.opensaml.ws.security.provider.MandatoryIssuerRule;
 import org.opensaml.ws.transport.http.HTTPInTransport;
 import org.opensaml.ws.transport.http.HTTPOutTransport;
-import org.opensaml.ws.transport.http.HttpServletRequestAdapter;
-import org.opensaml.ws.transport.http.HttpServletResponseAdapter;
 import org.opensaml.xml.security.credential.Credential;
 import org.opensaml.xml.util.Pair;
 
 import java.io.IOException;
+import java.net.HttpURLConnection;
 import java.net.URI;
 import java.net.URL;
 import java.util.Collection;
@@ -94,8 +83,6 @@
 
 import javax.annotation.concurrent.GuardedBy;
 import javax.annotation.concurrent.ThreadSafe;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 
 /**
  * A library implementing most of the functionality of a SAML service provider.
@@ -200,7 +187,7 @@
    * @return The assertion consumer service descriptor.
    */
   public AssertionConsumerService getPostAssertionConsumerService() {
-    return getAssertionConsumerService(MetadataEditor.SAML_BINDING_HTTP_POST);
+    return getAssertionConsumerService(SAMLConstants.SAML2_POST_BINDING_URI);
   }
 
   /**
@@ -209,7 +196,7 @@
    * @return The assertion consumer service descriptor.
    */
   public AssertionConsumerService getArtifactAssertionConsumerService() {
-    return getAssertionConsumerService(MetadataEditor.SAML_BINDING_HTTP_ARTIFACT);
+    return getAssertionConsumerService(SAMLConstants.SAML2_ARTIFACT_BINDING_URI);
   }
 
   private AssertionConsumerService getAssertionConsumerService(String binding) {
@@ -269,56 +256,6 @@
   }
 
   /**
-   * Decode a SAML response sent via the POST binding.
-   *
-   * @param request The HTTP request containing the encoded response.
-   * @return The decoded response, or null if there was an error decoding the message.  In
-   *     this case, a log file entry is generated, so the caller doesn't need to know the
-   *     details of the failure.
-   * @throws IOException for various errors related to session and metadata.
-   */
-  /*
-  // Commented out to prevent pulling in AuthnSession.
-  public Response decodePostResponse(HttpServletRequest request)
-      throws IOException {
-    AuthnSession session = AuthnSession.getInstance(request);
-    if (session == null) {
-      return null;
-    }
-    SAMLMessageContext<Response, SAMLObject, NameID> context =
-        makeSamlMessageContext();
-
-    initializeLocalEntity(context, localEntity, localEntity.getSPSSODescriptor(SAML20P_NS));
-    initializePeerEntity(context, peerEntity, peerEntity.getIDPSSODescriptor(SAML20P_NS),
-        SingleSignOnService.DEFAULT_ELEMENT_NAME,
-        SAML2_REDIRECT_BINDING_URI);
-
-    if (!peerSupportsSignatureVerification(context)) {
-      LOGGER.warning("SAML POST peer not configured for signature verification");
-      return null;
-    }
-
-    // Create a security policy to check the response signature.  Works only
-    // with certificates that are stored in the metadata.
-    context.setSecurityPolicyResolver(
-        makeStaticSecurityPolicyResolver(
-            getMetadataSignaturePolicyRule(request),
-            // Requires an <Issuer>:
-            new MandatoryIssuerRule(),
-            // Requires that the message be authenticated:
-            new MandatoryAuthenticatedMessageRule()));
-
-    context.setInboundMessageTransport(new HttpServletRequestAdapter(request));
-    if (!runDecoder(new HTTPPostDecoder(), context, session, "client identity provider")) {
-      return null;
-    }
-
-    Response samlResponse = context.getInboundSAMLMessage();
-    Preconditions.checkNotNull(samlResponse, "Decoded SAML response is null");
-    return samlResponse;
-  }*/
-
-  /**
    * Decode a SAML response sent via the artifact binding.
    *
    * @param request The HTTP request containing the artifact.
@@ -405,7 +342,7 @@
 
     // Do HTTP exchange.
     int status = exchange.exchange();
-    if (status != HttpServletResponse.SC_OK) {
+    if (status != HttpURLConnection.HTTP_OK) {
       LOGGER.warning("Incorrect HTTP status: " + status);
       return null;
     }
@@ -448,7 +385,7 @@
 
       // Do HTTP exchange
       int status = exchange.exchange();
-      if (!HttpUtil.isGoodHttpStatus(status)) {
+      if (!isGoodHttpStatus(status)) {
         throw new IOException("Incorrect HTTP status: " + status);
       }
 
@@ -511,7 +448,7 @@
 
       // Do HTTP exchange
       int status = exchange.exchange();
-      if (!HttpUtil.isGoodHttpStatus(status)) {
+      if (!isGoodHttpStatus(status)) {
         throw new IOException("Incorrect HTTP status: " + status);
       }
 
@@ -678,4 +615,9 @@
       return builder.buildURL();
     }
   }
+
+  public static boolean isGoodHttpStatus(int status) {
+    return status == HttpURLConnection.HTTP_OK
+        || status == HttpURLConnection.HTTP_PARTIAL;
+  }
 }
diff --git a/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextDecoder.java b/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextDecoder.java
index b997127..5021b89 100644
--- a/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextDecoder.java
+++ b/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextDecoder.java
@@ -27,11 +27,11 @@
 import org.opensaml.xml.XMLObject;
 import org.opensaml.xml.parse.ParserPool;
 import org.opensaml.xml.util.DatatypeHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 import javax.xml.namespace.QName;
 
@@ -42,7 +42,7 @@
 public class HTTPSOAP11MultiContextDecoder extends BaseSAML2MessageDecoder {
 
   /** Class logger. */
-  private final Logger log = LoggerFactory.getLogger(HTTPSOAP11MultiContextDecoder.class);
+  private static final Logger log = Logger.getLogger(HTTPSOAP11MultiContextDecoder.class.getName());
 
   /** QNames of understood SOAP headers. */
   private final List<QName> understoodHeaders = new ArrayList<QName>();
@@ -102,7 +102,6 @@
   @Override
   protected void doDecode(MessageContext messageContext) throws MessageDecodingException {
     if (!(messageContext instanceof SAMLMessageContext<?, ?, ?>)) {
-      log.error("Invalid message context type, this decoder only support SAMLMessageContext");
       throw new MessageDecodingException(
           "Invalid message context type, this decoder only support SAMLMessageContext");
     }
@@ -116,10 +115,9 @@
     }
 
     if (soapBodyChildren.size() < 1) {
-      log.error("Unexpected number of children in the SOAP body, " + soapBodyChildren.size()
-          + ".  Unable to extract SAML message");
       throw new MessageDecodingException(
-          "Unexpected number of children in the SOAP body, unable to extract SAML message");
+          "Unexpected number of children in the SOAP body, " + soapBodyChildren.size()
+          + ". Unable to extract SAML message");
     }
 
     if (thisChild >= soapBodyChildren.size()) {
@@ -132,16 +130,15 @@
     thisChild++;
 
     if (!(incomingMessage instanceof SAMLObject)) {
-      log.error("Unexpected SOAP body content.  Expected a SAML request but recieved {}",
-          incomingMessage.getElementQName());
       throw new MessageDecodingException(
           "Unexpected SOAP body content.  Expected a SAML request but recieved "
               + incomingMessage.getElementQName());
     }
     SAMLObject samlMessage = (SAMLObject) incomingMessage;
 
-    log.debug("Decoded SOAP messaged which included SAML message of type {}",
-              samlMessage.getElementQName());
+    log.log(Level.FINE,
+        "Decoded SOAP messaged which included SAML message of type {}",
+        samlMessage.getElementQName());
     samlMsgCtx.setInboundSAMLMessage(samlMessage);
 
     populateMessageContext(samlMsgCtx);
@@ -183,8 +180,6 @@
   private void start(SAMLMessageContext<SAMLObject, SAMLObject, SAMLObject> samlMsgCtx)
       throws MessageDecodingException {
     if (!(samlMsgCtx.getInboundMessageTransport() instanceof HTTPInTransport)) {
-      log.error(
-          "Invalid inbound message transport type, this decoder only support HTTPInTransport");
       throw new MessageDecodingException(
           "Invalid inbound message transport type, this decoder only support HTTPInTransport");
     }
@@ -195,7 +190,7 @@
           "This message deocoder only supports the HTTP POST method");
     }
 
-    log.debug("Unmarshalling SOAP message");
+    log.fine("Unmarshalling SOAP message");
     soapMessage = Envelope.class.cast(unmarshallMessage(inTransport.getIncomingStream()));
 
     Header messageHeader = soapMessage.getHeader();
diff --git a/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextEncoder.java b/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextEncoder.java
index f982483..0794408 100644
--- a/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextEncoder.java
+++ b/src/com/google/enterprise/secmgr/saml/HTTPSOAP11MultiContextEncoder.java
@@ -28,14 +28,13 @@
 import org.opensaml.ws.transport.http.HTTPTransportUtils;
 import org.opensaml.xml.XMLObjectBuilderFactory;
 import org.opensaml.xml.util.XMLHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
 
 import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
+import java.util.logging.Logger;
 
 /**
  * SAML 2.0 SOAP 1.1 over HTTP MultiContext binding encoder.
@@ -48,7 +47,7 @@
   private HTTPOutTransport outTransport;
 
   /** Class logger. */
-  private final Logger log = LoggerFactory.getLogger(HTTPSOAP11MultiContextEncoder.class);
+  private static final Logger log = Logger.getLogger(HTTPSOAP11MultiContextEncoder.class.getName());
 
   /** Constructor. */
   public HTTPSOAP11MultiContextEncoder() {
@@ -78,7 +77,6 @@
   @Override
   protected void doEncode(MessageContext messageContext) throws MessageEncodingException {
     if (!(messageContext instanceof SAMLMessageContext<?, ?, ?>)) {
-      log.error("Invalid message context type, this encoder only supports SAMLMessageContext");
       throw new MessageEncodingException(
           "Invalid message context type, this encoder only supports SAMLMessageContext");
     }
@@ -87,8 +85,6 @@
         (SAMLMessageContext<SAMLObject, SAMLObject, SAMLObject>) messageContext;
 
     if (!(messageContext.getOutboundMessageTransport() instanceof HTTPOutTransport)) {
-      log.error(
-          "Invalid outbound message transport type, this encoder only supports HTTPOutTransport");
       throw new MessageEncodingException(
           "Invalid outbound message transport type, this encoder only supports HTTPOutTransport");
     }
@@ -106,9 +102,7 @@
     signMessage(samlMsgCtx);
     samlMsgCtx.setOutboundMessage(envelope);
 
-    if (log.isDebugEnabled()) {
-      log.debug("Adding SAML message to the SOAP message's body");
-    }
+    log.fine("Adding SAML message to the SOAP message's body");
 
     body.getUnknownXMLObjects().add(samlMessage);
   }
@@ -124,10 +118,8 @@
       XMLHelper.writeNode(envelopeElem, out);
       out.flush();
     } catch (UnsupportedEncodingException e) {
-      log.error("JVM does not support required UTF-8 encoding");
       throw new MessageEncodingException("JVM does not support required UTF-8 encoding");
     } catch (IOException e) {
-      log.error("Unable to write message content to outbound stream", e);
       throw new MessageEncodingException("Unable to write message content to outbound stream", e);
     }
   }
@@ -136,9 +128,7 @@
    * Builds the SOAP message to be encoded.
    */
   protected void buildSOAPMessage() {
-    if (log.isDebugEnabled()) {
-      log.debug("Building SOAP message");
-    }
+    log.fine("Building SOAP message");
     XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
 
     @SuppressWarnings("unchecked")
diff --git a/src/com/google/enterprise/secmgr/saml/Metadata.java b/src/com/google/enterprise/secmgr/saml/Metadata.java
deleted file mode 100644
index df06562..0000000
--- a/src/com/google/enterprise/secmgr/saml/Metadata.java
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2008 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.saml;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Maps;
-import com.google.enterprise.secmgr.common.FileUtil;
-import com.google.enterprise.secmgr.common.SecurityManagerUtil;
-import com.google.enterprise.secmgr.common.XmlUtil;
-import com.google.enterprise.secmgr.config.ConfigSingleton;
-
-import org.opensaml.saml2.metadata.EntitiesDescriptor;
-import org.opensaml.saml2.metadata.EntityDescriptor;
-import org.opensaml.saml2.metadata.provider.AbstractObservableMetadataProvider;
-import org.opensaml.saml2.metadata.provider.MetadataProvider;
-import org.opensaml.saml2.metadata.provider.MetadataProviderException;
-import org.opensaml.saml2.metadata.provider.ObservableMetadataProvider;
-import org.opensaml.xml.XMLObject;
-import org.opensaml.xml.io.MarshallingException;
-import org.opensaml.xml.io.UnmarshallingException;
-import org.w3c.dom.CDATASection;
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.EntityReference;
-import org.w3c.dom.NamedNodeMap;
-import org.w3c.dom.Node;
-import org.w3c.dom.ProcessingInstruction;
-import org.w3c.dom.Text;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Map;
-import java.util.logging.Logger;
-
-import javax.annotation.concurrent.GuardedBy;
-import javax.annotation.concurrent.ThreadSafe;
-
-/**
- * An abstract interface to the SAML metadata configuration.  Tracks a given
- * metadata file and keeps it up to date.  Also rewrites the metadata so it uses
- * the correct hostname.
- */
-@ThreadSafe
-public class Metadata {
-
-  private static final Logger LOGGER = Logger.getLogger(Metadata.class.getName());
-
-  @GuardedBy("itself")
-  private static final Map<String, Metadata> perHostMap = Maps.newHashMap();
-  private static File metadataFile = null;
-
-  private final MetadataProvider provider;
-
-  private Metadata(String urlPrefix)
-      throws IOException {
-    try {
-      this.provider = new MyProvider(
-          OpenSamlUtil.getMetadataFromFile(
-              (metadataFile != null)
-              ? metadataFile
-              : FileUtil.getContextFile(ConfigSingleton.getSamlMetadataFilename())),
-          urlPrefix, SecurityManagerUtil.getGsaEntConfigName());
-    } catch (MetadataProviderException e) {
-      throw new IOException(e);
-    }
-  }
-
-  @VisibleForTesting
-  static void setMetadataFile(File metadataFile) {
-    Metadata.metadataFile = metadataFile;
-  }
-
-  @VisibleForTesting
-  public static Metadata getInstance(String host)
-      throws IOException {
-    return getInstance("http", host);
-  }
-
-  public static Metadata getInstance(URL url)
-      throws IOException {
-    return getInstance(url.getProtocol(), url.getHost());
-  }
-
-  public static Metadata getInstance(String protocol, String host)
-      throws IOException {
-    String urlPrefix = protocol + "://" + host;
-    Metadata result;
-    synchronized (perHostMap) {
-      result = perHostMap.get(urlPrefix);
-      if (result == null) {
-        result = new Metadata(urlPrefix);
-        perHostMap.put(urlPrefix, result);
-      }
-    }
-    return result;
-  }
-
-  public MetadataProvider getProvider() {
-    return provider;
-  }
-
-  public EntitiesDescriptor getMetadata() throws IOException {
-    XMLObject root;
-    try {
-      root = provider.getMetadata();
-    } catch (MetadataProviderException e) {
-      throw new IOException(e);
-    }
-    if (root instanceof EntitiesDescriptor) {
-      return (EntitiesDescriptor) root;
-    }
-    throw new IOException("Malformed SAML metadata");
-  }
-
-  public EntityDescriptor getEntity(String id) throws IOException {
-    EntityDescriptor entity;
-    try {
-      entity = provider.getEntityDescriptor(id);
-    } catch (MetadataProviderException e) {
-      throw new IOException(e);
-    }
-    if (entity == null) {
-      throw new IllegalArgumentException("Unknown entity ID: " + id);
-    }
-    return entity;
-  }
-
-  public EntityDescriptor getSmEntity() throws IOException {
-    for (EntityDescriptor e : getMetadata().getEntityDescriptors()) {
-      if (MetadataEditor.SECMGR_ID_FOR_ENTITY.equals(e.getID())) {
-        return e;
-      }
-    }
-    throw new IllegalStateException("Can't find security manager's entity descriptor");
-  }
-
-  public String getSmEntityId() throws IOException {
-    return getSmEntity().getEntityID();
-  }
-
-  /**
-   * This class implements a wrapper around an OpenSAML
-   * ObservableMetadataProvider that customizes the metadata for a particular
-   * host.  When the metadata is updated, as when the configuration file is
-   * changed, this provider notices that, gets the updated metadata, and
-   * customizes it.  To speed things up a bit, the customized metadata is
-   * cached, so it need not be customized every time.
-   */
-  private static class MyProvider
-      extends AbstractObservableMetadataProvider
-      implements ObservableMetadataProvider.Observer {
-
-    private final ObservableMetadataProvider wrappedProvider;
-    private final String urlPrefix;
-    private final String gsaEntConfigName;
-    private XMLObject savedMetadata;
-
-    public MyProvider(ObservableMetadataProvider wrappedProvider,
-        String urlPrefix, String gsaEntConfigName) {
-      super();
-      this.wrappedProvider = wrappedProvider;
-      this.urlPrefix = urlPrefix;
-      this.gsaEntConfigName = gsaEntConfigName;
-      savedMetadata = null;
-      wrappedProvider.getObservers().add(this);
-    }
-
-    public synchronized void onEvent(MetadataProvider provider) {
-      LOGGER.info("Clearing cached metadata");
-      savedMetadata = null;
-      emitChangeEvent();
-    }
-
-    public synchronized XMLObject getMetadata() throws MetadataProviderException {
-      // This will call onEvent if the file has changed:
-      XMLObject rawMetadata = wrappedProvider.getMetadata();
-      if (savedMetadata == null) {
-        try {
-          savedMetadata = OpenSamlUtil.unmarshallXmlObject(
-              substituteTopLevel(
-                  OpenSamlUtil.marshallXmlObject(rawMetadata)));
-        } catch (MarshallingException e) {
-          throw new MetadataProviderException(e);
-        } catch (UnmarshallingException e) {
-          throw new MetadataProviderException(e);
-        }
-      }
-      return savedMetadata;
-    }
-
-    private Element substituteTopLevel(Element element) {
-      Document doc = XmlUtil.getInstance()
-          .makeDocument(element.getNamespaceURI(), element.getTagName(), null);
-      Element newElement = doc.getDocumentElement();
-      substituteInNodeChildren(element, newElement, doc);
-      return newElement;
-    }
-
-    private void substituteInNodeChildren(Node node, Node newNode, Document doc) {
-      if (node instanceof Element) {
-        NamedNodeMap attrs = node.getAttributes();
-        NamedNodeMap newAttrs = newNode.getAttributes();
-        for (int i = 0; i < attrs.getLength(); i++) {
-          Node attr = attrs.item(i);
-          Node newAttr = doc.createAttributeNS(attr.getNamespaceURI(), attr.getNodeName());
-          newAttr.setNodeValue(substituteInString(attr.getNodeValue()));
-          newAttrs.setNamedItemNS(newAttr);
-        }
-      }
-      for (Node child = node.getFirstChild(); child != null; child = child.getNextSibling()) {
-        Node newChild = substituteInNode(child, doc);
-        substituteInNodeChildren(child, newChild, doc);
-        newNode.appendChild(newChild);
-      }
-    }
-
-    private Node substituteInNode(Node node, Document doc) {
-      if (node instanceof Element) {
-        return doc.createElementNS(node.getNamespaceURI(), node.getNodeName());
-      } else if (node instanceof Text) {
-        return doc.createTextNode(substituteInString(node.getNodeValue()));
-      } else if (node instanceof CDATASection) {
-        return doc.createCDATASection(node.getNodeValue());
-      } else if (node instanceof Comment) {
-        return doc.createComment(node.getNodeValue());
-      } else if (node instanceof EntityReference) {
-        return doc.createEntityReference(node.getNodeName());
-      } else if (node instanceof ProcessingInstruction) {
-        return doc.createProcessingInstruction(node.getNodeName(), node.getNodeValue());
-      } else {
-        throw new IllegalArgumentException("Unknown node type: " + node.getNodeType());
-      }
-    }
-
-    private String substituteInString(String original) {
-      if (original == null) { return original; }
-      String pattern = "https://" + MetadataEditor.GSA_HOST_MARKER;
-      if (original.startsWith(pattern)) {
-        return original.replace(pattern, urlPrefix);
-      }
-      pattern = "http://" + MetadataEditor.GSA_HOST_MARKER;
-      if (original.startsWith(pattern)) {
-        return original.replace(pattern, urlPrefix);
-      }
-      if (original.contains(MetadataEditor.GSA_ENT_CONFIG_NAME_MARKER)) {
-        return original.replace(MetadataEditor.GSA_ENT_CONFIG_NAME_MARKER, gsaEntConfigName);
-      }
-      return original;
-    }
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/saml/MetadataEditor.java b/src/com/google/enterprise/secmgr/saml/MetadataEditor.java
deleted file mode 100644
index 933ed08..0000000
--- a/src/com/google/enterprise/secmgr/saml/MetadataEditor.java
+++ /dev/null
@@ -1,1069 +0,0 @@
-// Copyright 2009 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.secmgr.saml;
-
-import static com.google.enterprise.secmgr.common.XmlUtil.countChildElements;
-import static com.google.enterprise.secmgr.common.XmlUtil.findChildComments;
-import static com.google.enterprise.secmgr.common.XmlUtil.findChildElement;
-import static com.google.enterprise.secmgr.common.XmlUtil.getElementsByQname;
-import static com.google.enterprise.secmgr.common.XmlUtil.makeCommentChild;
-import static com.google.enterprise.secmgr.common.XmlUtil.makeElement;
-import static com.google.enterprise.secmgr.common.XmlUtil.makeElementChild;
-import static com.google.enterprise.secmgr.common.XmlUtil.makeTextChild;
-import static com.google.enterprise.secmgr.common.XmlUtil.makeTextElementChild;
-import static com.google.enterprise.secmgr.common.XmlUtil.setConfigParams;
-
-import com.google.common.base.Objects;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-import com.google.enterprise.secmgr.common.XmlUtil;
-
-import org.w3c.dom.Comment;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.Writer;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.Collection;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.annotation.concurrent.Immutable;
-import javax.xml.crypto.dsig.XMLSignature;
-import javax.xml.namespace.QName;
-
-/**
- * Utilities for editing SAML metadata files.
- */
-@Immutable
-public class MetadataEditor {
-  private static final Logger LOGGER = Logger.getLogger(MetadataEditor.class.getName());
-
-  // SAML metadata elements.
-  public static final String SAML_MD_NS = "urn:oasis:names:tc:SAML:2.0:metadata";
-
-  private static QName mdName(String localPart) {
-    return new QName(SAML_MD_NS, localPart);
-  }
-
-  public static final QName SAML_DESCRIPTOR_ENTITIES = mdName("EntitiesDescriptor");
-  public static final QName SAML_DESCRIPTOR_ENTITY = mdName("EntityDescriptor");
-  public static final QName SAML_DESCRIPTOR_IDP_SSO = mdName("IDPSSODescriptor");
-  public static final QName SAML_DESCRIPTOR_KEY = mdName("KeyDescriptor");
-  public static final QName SAML_DESCRIPTOR_PDP = mdName("PDPDescriptor");
-  public static final QName SAML_DESCRIPTOR_SP_SSO = mdName("SPSSODescriptor");
-  public static final QName SAML_ORGANIZATION = mdName("Organization");
-  public static final QName SAML_ORGANIZATION_DISPLAY_NAME = mdName("OrganizationDisplayName");
-  public static final QName SAML_ORGANIZATION_NAME = mdName("OrganizationName");
-  public static final QName SAML_ORGANIZATION_URL = mdName("OrganizationURL");
-  public static final QName SAML_SERVICE_ARTIFACT_RESOLUTION = mdName("ArtifactResolutionService");
-  public static final QName SAML_SERVICE_ASSERTION_CONSUMER = mdName("AssertionConsumerService");
-  public static final QName SAML_SERVICE_AUTHZ = mdName("AuthzService");
-  public static final QName SAML_SERVICE_SINGLE_SIGN_ON = mdName("SingleSignOnService");
-
-  // SAML metadata attributes.
-  public static final String SAML_ATTR_BINDING = "Binding";
-  public static final String SAML_ATTR_CACHE_DURATION = "cacheDuration";
-  public static final String SAML_ATTR_ENTITY_ID = "entityID";
-  public static final String SAML_ATTR_INDEX = "index";
-  public static final String SAML_ATTR_IS_DEFAULT = "isDefault";
-  public static final String SAML_ATTR_LOCATION = "Location";
-  public static final String SAML_ATTR_NAME = "Name";
-  public static final String SAML_ATTR_PROTOCOL_SUPPORT_ENUMERATION = "protocolSupportEnumeration";
-  public static final String SAML_ATTR_USE = "use";
-  public static final String XML_ATTR_ID = "ID";
-
-  // SAML metadata attribute values.
-  public static final String SAML_BINDING_HTTP_ARTIFACT =
-      "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact";
-  public static final String SAML_BINDING_HTTP_POST =
-      "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
-  public static final String SAML_BINDING_HTTP_REDIRECT =
-      "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect";
-  public static final String SAML_BINDING_SOAP = "urn:oasis:names:tc:SAML:2.0:bindings:SOAP";
-  public static final String SAML_PROTOCOL = "urn:oasis:names:tc:SAML:2.0:protocol";
-  public static final String SAML_USAGE_SIGNING = "signing";
-  private static final String SAML_CACHE_DURATION = "PT1H";  // one hour
-
-  // Entity group for SAML clients.
-  public static final String SECMGR_CLIENTS_ENTITIES_NAME = "security-manager-clients";
-  public static final String SECMGR_CLIENTS_ENTITIES_COMMENT = "SAML client IdPs";
-
-  // XML Digital Signature elements.
-  private static QName dsName(String localPart) {
-    return new QName(XMLSignature.XMLNS, localPart, "ds");
-  }
-
-  public static final QName XMLDSIG_KEY_INFO = dsName("KeyInfo");
-  public static final QName XMLDSIG_X509_DATA = dsName("X509Data");
-  public static final QName XMLDSIG_X509_CERTIFICATE = dsName("X509Certificate");
-
-  // Entity for GSA.
-  public static final String GSA_ENTITY_ID_ROOT = "http://google.com/enterprise/gsa/";
-  public static final String GSA_ENTITY_COMMENT = "Description of the GSA";
-  public static final String GSA_ENT_CONFIG_NAME_MARKER = "${ENT_CONFIG_NAME}";
-
-  // Entity for security manager.
-  public static final String SECMGR_ENTITY_ID_SUFFIX = "/security-manager";
-  public static final String SECMGR_ENTITY_COMMENT = "Description of the Security Manager";
-  static final String SECMGR_ID_FOR_ENTITY = "security-manager";
-
-  // Google organization element.
-  public static final String GOOGLE_ORGANIZATION_NAME = "google.com";
-  public static final String GOOGLE_ORGANIZATION_DISPLAY_NAME = "Google Inc.";
-  public static final String GOOGLE_ORGANIZATION_URL = "http://www.google.com/";
-
-  // Endpoint URLs.
-  private static final String HTTP_PROTOCOL = "http";
-  private static final String HTTPS_PROTOCOL = "https";
-  static final String GSA_HOST_MARKER = "$$GSA$$";
-  private static final String SECMGR_WEBAPP_PATH = "/security-manager";
-  private static final String LOCALHOST = "localhost";
-
-  public static final String GSA_ASSERTION_CONSUMER_PATH = "SamlArtifactConsumer";
-
-  public static final String SECMGR_SSO_PATH = "samlauthn";
-  public static final String SECMGR_ARTIFACT_RESOLVER_PATH = "samlartifact";
-  public static final String SECMGR_ASSERTION_CONSUMER_PATH = "samlassertionconsumer";
-  public static final String SECMGR_AUTHZ_PATH = "samlauthz";
-  public static final String X509_HEADER = "-----BEGIN CERTIFICATE-----";
-  public static final String X509_FOOTER = "-----END CERTIFICATE-----";
-
-  // Don't instantiate this class.
-  private MetadataEditor() {}
-
-  /**
-   * A datatype to hold the parameters of a SAML client IdP.
-   */
-  @Immutable
-  public static class SamlClientIdp {
-
-    private final String id;
-    private final String loginUrl;
-    private final String artifactUrl;
-    private final String certificate;
-    private final String authzServiceUrl;
-
-    private SamlClientIdp(String id, String loginUrl, String artifactUrl, String certificate,
-        String authzServiceUrl) {
-      Preconditions.checkNotNull(id);
-      this.id = id;
-      this.loginUrl = loginUrl;
-      this.artifactUrl = artifactUrl;
-      this.certificate = normalizeCertificate(certificate);
-      this.authzServiceUrl = authzServiceUrl;
-    }
-
-    /**
-     * Make a client with only IDP SSO components.
-     *
-     * @param id The entity ID for the IdP.
-     * @param loginUrl The single sign-on service URL for the IdP.
-     * @param artifactUrl The artifact resolution service URL for the IdP, or null if none.
-     * @param certificate A PEM encoded X509 certificate, or null if none.
-     * @return A new IDP SSO client.
-     */
-    public static SamlClientIdp makeSso(String id, String loginUrl, String artifactUrl,
-        String certificate) {
-      Preconditions.checkNotNull(loginUrl);
-      Preconditions.checkArgument(artifactUrl != null ^ certificate != null);
-      return new SamlClientIdp(id, loginUrl, artifactUrl, certificate, null);
-    }
-
-    /**
-     * Make a client with only PDP components.
-     *
-     * @param id The entity ID for the PDP.
-     * @param authzServiceUrl The URL for the PDP's AuthzService.
-     * @return A new PDP client.
-     */
-    public static SamlClientIdp makePdp(String id, String authzServiceUrl) {
-      Preconditions.checkNotNull(authzServiceUrl);
-      return new SamlClientIdp(id, null, null, null, authzServiceUrl);
-    }
-
-    /**
-     * @return True if this client has IdP SSO components.
-     */
-    public boolean hasSso() {
-      return loginUrl != null && (artifactUrl != null || certificate != null);
-    }
-
-    /**
-     * @return True if this client has PDP components.
-     */
-    public boolean hasPdp() {
-      return authzServiceUrl != null;
-    }
-
-    /**
-     * @return True if this client has components other than IDP SSO.
-     */
-    public boolean hasNonSso() {
-      return hasPdp();
-    }
-
-    /**
-     * @return True if this client has components other than PDP.
-     */
-    public boolean hasNonPdp() {
-      return hasSso();
-    }
-
-    /**
-     * Replace the IDP SSO components of this client with those of another.
-     *
-     * @param client The client to get the IDP SSO components from.
-     * @return A copy of this client with its IDP SSO components replaced.
-     */
-    public SamlClientIdp replaceSso(SamlClientIdp client) {
-      return new SamlClientIdp(id,
-          client.getUrl(),
-          client.getArtifactUrl(),
-          client.getCertificate(),
-          authzServiceUrl);
-    }
-
-    /**
-     * @return A copy of this client with its IDP SSO components removed.
-     */
-    public SamlClientIdp removeSso() {
-      return new SamlClientIdp(id, null, null, null, authzServiceUrl);
-    }
-
-    /**
-     * Replace the PDP components of this client with those of another.
-     *
-     * @param client The client to get the PDP components from.
-     * @return A copy of this client with its PDP components replaced.
-     */
-    public SamlClientIdp replacePdp(SamlClientIdp client) {
-      return new SamlClientIdp(id,
-          loginUrl,
-          artifactUrl,
-          certificate,
-          client.getAuthzServiceUrl());
-    }
-
-    /**
-     * @return A copy of this client with its PDP components removed.
-     */
-    public SamlClientIdp removePdp() {
-      return new SamlClientIdp(id, loginUrl, artifactUrl, certificate, null);
-    }
-
-    /**
-     * @return The entity ID of the SAML client.
-     */
-    public String getId() {
-      return id;
-    }
-
-    /**
-     * @return The single-sign-on entry URL for the SAML client.
-     */
-    public String getUrl() {
-      return loginUrl;
-    }
-
-    /**
-     * @return The artifact-resolution entry URL for the SAML client, or null if none.
-     */
-    public String getArtifactUrl() {
-      return artifactUrl;
-    }
-
-    /**
-     * @return The signing certificate for the SAML client, or null if none.
-     */
-    public String getCertificate() {
-      return certificate;
-    }
-
-    /**
-     * @return The AuthzService URL for the SAML client.
-     */
-    public String getAuthzServiceUrl() {
-      return authzServiceUrl;
-    }
-
-    @Override
-    public int hashCode() {
-      return Objects.hashCode(id, loginUrl, artifactUrl, certificate, authzServiceUrl);
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-      if (obj == this) { return true; }
-      if (!(obj instanceof SamlClientIdp)) { return false; }
-      SamlClientIdp other = (SamlClientIdp) obj;
-      return Objects.equal(id, other.id)
-          && Objects.equal(loginUrl, other.loginUrl)
-          && Objects.equal(artifactUrl, other.artifactUrl)
-          && Objects.equal(certificate, other.certificate)
-          && Objects.equal(authzServiceUrl, other.authzServiceUrl);
-    }
-  }
-
-  /**
-   * Get the SAML client IdPs from metadata.
-   *
-   * @param document The metadata as a {@link Document}.
-   * @return A list of SAML client IdP descriptors.
-   * @throws IllegalArgumentException if metadata can't be parsed.
-   */
-  public static List<SamlClientIdp> getSamlClientsInMetadata(Document document) {
-    List<SamlClientIdp> clients = Lists.newArrayList();
-    Set<String> idsSeen = Sets.newHashSet();
-    Element entities = getSamlClients(document);
-    if (entities != null) {
-      NodeList nodes = getElementsByQname(entities, SAML_DESCRIPTOR_ENTITY);
-      for (int index = 0; index < nodes.getLength(); index++) {
-        Element element = Element.class.cast(nodes.item(index));
-        SamlClientIdp client;
-        try {
-          client = parseClient(element, idsSeen);
-        } catch (IllegalArgumentException e) {
-          LOGGER.log(Level.WARNING, "Unable to parse SAML client spec: ", e);
-          client = null;
-        }
-        if (client != null) {
-          clients.add(client);
-        }
-      }
-    }
-    return clients;
-  }
-
-  private static SamlClientIdp parseClient(Element element, Set<String> idsSeen) {
-    String id = element.getAttribute(SAML_ATTR_ENTITY_ID);
-    Preconditions.checkArgument(!idsSeen.contains(id), "Duplicate entity ID in metadata: %s", id);
-    idsSeen.add(id);
-    SamlClientIdp sso = parseSso(id, findChildElement(element, SAML_DESCRIPTOR_IDP_SSO, false));
-    SamlClientIdp pdp = parsePdp(id, findChildElement(element, SAML_DESCRIPTOR_PDP, false));
-    return
-        (sso == null) ? pdp
-        : (pdp == null) ? sso
-        : sso.replacePdp(pdp);
-  }
-
-  private static SamlClientIdp parseSso(String id, Element ssoRole) {
-    if (ssoRole == null) {
-      return null;
-    }
-    Element sso = findChildElement(ssoRole, SAML_SERVICE_SINGLE_SIGN_ON, true);
-    Element ars = findChildElement(ssoRole, SAML_SERVICE_ARTIFACT_RESOLUTION, false);
-    Element kd = findChildElement(ssoRole, SAML_DESCRIPTOR_KEY, false);
-    return SamlClientIdp.makeSso(id,
-        sso.getAttribute(SAML_ATTR_LOCATION),
-        (ars == null) ? null : ars.getAttribute(SAML_ATTR_LOCATION),
-        (kd == null) ? null : keyDescriptorCertificate(kd));
-  }
-
-  private static SamlClientIdp parsePdp(String id, Element pdp) {
-    if (pdp == null) {
-      return null;
-    }
-    Element authz = findChildElement(pdp, SAML_SERVICE_AUTHZ, true);
-    return SamlClientIdp.makePdp(id,
-        (authz == null) ? null : authz.getAttribute(SAML_ATTR_LOCATION));
-  }
-
-  /**
-   * Set the SAML client IdPs in given metadata to the given set.  Removes any
-   * clients already in the metadata, then inserts the given clients.
-   *
-   * @param document The metadata as a {@link Document}.  This document is
-   *     modified to contain the new clients.
-   * @param clients A set of SAML client IdP descriptors; null means delete all.
-   * @throws IOException if metadata can't be parsed or serialized.
-   */
-  public static void setSamlClientsInMetadata(Document document, Collection<SamlClientIdp> clients)
-      throws IOException {
-    if (clients == null) {
-      deleteSamlClients(document);
-      return;
-    }
-    Set<String> idsSeen = Sets.newHashSet();
-    checkSamlClients(idsSeen, clients);
-    deleteSamlClients(document);
-    for (SamlClientIdp client : clients) {
-      addIdpEntity(document, client);
-    }
-  }
-
-  /**
-   * Add the given SAML client IdPs to the given metadata.
-   *
-   * @param document The metadata as a {@link Document}.  This document is
-   *     modified to contain the new clients.
-   * @param clients A set of SAML client IdP descriptors; never null.
-   * @throws IOException if metadata can't be parsed or serialized.
-   */
-  public static void addSamlClientsToMetadata(Document document, Collection<SamlClientIdp> clients)
-      throws IOException {
-    Set<String> idsSeen = Sets.newHashSet();
-    for (SamlClientIdp client : getSamlClientsInMetadata(document)) {
-      idsSeen.add(client.getId());
-    }
-    checkSamlClients(idsSeen, clients);
-    for (SamlClientIdp client : clients) {
-      addIdpEntity(document, client);
-    }
-  }
-
-  private static void checkSamlClients(Set<String> idsSeen, Collection<SamlClientIdp> clients) {
-    for (SamlClientIdp client : clients) {
-      Preconditions.checkArgument(!idsSeen.contains(client.getId()),
-          "Duplicate entity ID in clients: %s", client.getId());
-      idsSeen.add(client.getId());
-    }
-  }
-
-  /**
-   * Find a SAML client with a given entity ID.
-   *
-   * @param entityId The entity ID to look for.
-   * @param clients The clients to look through.
-   * @return The client with that ID, or null if none.
-   */
-  public static SamlClientIdp findSamlClient(String entityId, Iterable<SamlClientIdp> clients) {
-    for (SamlClientIdp client : clients) {
-      if (entityId.equals(client.getId())) {
-        return client;
-      }
-    }
-    return null;
-  }
-
-  // **************** Versions of the above using XML strings ****************
-
-  /**
-   * Get the SAML client IdPs from metadata.
-   *
-   * @param metadata The metadata as XML String.
-   * @return A list of SAML client IdP descriptors.
-   * @throws IOException if metadata can't be parsed.
-   */
-  public static List<SamlClientIdp> getSamlClientsInMetadata(String metadata)
-      throws IOException {
-    return getSamlClientsInMetadata(stringToMetadataDocument(metadata));
-  }
-
-  /**
-   * Set the SAML client IdPs in given metadata to the given set.  Removes any
-   * clients already in the metadata, then inserts the given clients.
-   *
-   * @param origMetadata The original metadata as an XML String.
-   * @param clients The SAML client IdP descriptors; null means delete all.
-   * @return The new metadata as XML String.
-   * @throws IOException if metadata can't be parsed or serialized.
-   */
-  public static String setSamlClientsInMetadata(String origMetadata,
-      Collection<SamlClientIdp> clients)
-      throws IOException {
-    Document document = stringToMetadataDocument(origMetadata);
-    setSamlClientsInMetadata(document, clients);
-    return metadataDocumentToString(document);
-  }
-
-  /**
-   * Add the given SAML client IdPs to the given metadata.
-   *
-   * @param origMetadata The original metadata as an XML String.
-   * @param clients The SAML client IdP descriptors; never null.
-   * @return The new metadata as an XML String.
-   * @throws IOException if metadata can't be parsed or serialized.
-   */
-  public static String addSamlClientsToMetadata(String origMetadata,
-      Collection<SamlClientIdp> clients)
-      throws IOException {
-    Document document = stringToMetadataDocument(origMetadata);
-    addSamlClientsToMetadata(document, clients);
-    return metadataDocumentToString(document);
-  }
-
-  /**
-   * Parse a metadata string into an XML document.
-   *
-   * @param metadata The metadata as an XML string.
-   * @return The SAML metadata document.
-   * @throws IOException if the metadata can't be parsed.
-   */
-  public static Document stringToMetadataDocument(String metadata)
-      throws IOException {
-    return readMetadataDocument(new StringReader(metadata));
-  }
-
-  /**
-   * Convert a metadata XML document into a string.
-   *
-   * @param metadata The SAML metadata document.
-   * @return The metadata as an XML string.
-   * @throws IOException if the metadata can't be converted.
-   */
-  public static String metadataDocumentToString(Document metadata)
-      throws IOException {
-    return XmlUtil.getInstance().buildXmlString(metadata);
-  }
-
-  /**
-   * Read SAML metadata and return it as a DOM document.
-   *
-   * @param input The Reader to read from.
-   * @return The SAML metadata document.
-   * @throws IOException if the document can't be parsed.
-   */
-  public static Document readMetadataDocument(Reader input)
-      throws IOException {
-    Document document = XmlUtil.getInstance().readXmlDocument(input);
-    setConfigParams(document);
-    return document;
-  }
-
-  /**
-   * Write a SAML metadata document as XML.
-   *
-   * @param document The SAML metadata document to write.
-   * @param writer The writer to write it to.
-   * @throws IOException if the document can't be serialized.
-   */
-  public static void writeMetadataDocument(Document document, Writer writer)
-      throws IOException {
-    XmlUtil.getInstance().writeXmlDocument(document, writer);
-  }
-
-  /**
-   * Read SAML metadata and return it as a DOM document.
-   *
-   * @param file The file to read from.
-   * @return The SAML metadata document.
-   * @throws IOException if the document can't be parsed.
-   */
-  public static Document readMetadataDocument(File file)
-      throws IOException {
-    Reader reader = new FileReader(file);
-    try {
-      return readMetadataDocument(reader);
-    } finally {
-      reader.close();
-    }
-  }
-
-  /**
-   * Write a SAML metadata document as XML.
-   *
-   * @param document The SAML metadata document to write.
-   * @param file The file to write it to.
-   * @throws IOException if the document can't be serialized.
-   */
-  public static void writeMetadataDocument(Document document, File file)
-      throws IOException {
-    Writer writer = new FileWriter(file);
-    try {
-      writeMetadataDocument(document, writer);
-    } finally {
-      writer.close();
-    }
-  }
-
-  /**
-   * Make a default metadata document for the security manager, when it is installed
-   * onboard the GSA.  This metadata uses the token "$$GSA$$" to represent the hostname of
-   * the GSA; this token will be dynamically replaced with the real hostname on each
-   * request.  URLs that identify endpoints for connections between the GSA and the
-   * security manager use "localhost".
-   *
-   * @return An XML document representing the metadata.
-   */
-  public static Document makeOnboardSecurityManagerMetadata() {
-    Document document = XmlUtil.getInstance()
-        .makeDocument(SAML_DESCRIPTOR_ENTITIES.getNamespaceURI(),
-            SAML_DESCRIPTOR_ENTITIES.getLocalPart(),
-            null);
-    setConfigParams(document);
-    Element entities = document.getDocumentElement();
-    entities.setAttribute(SAML_ATTR_CACHE_DURATION, SAML_CACHE_DURATION);
-    String gsaEntityId = GSA_ENTITY_ID_ROOT + GSA_ENT_CONFIG_NAME_MARKER;
-    makeGsaEntity(entities, gsaEntityId);
-    makeSmEntity(entities, gsaEntityId + SECMGR_ENTITY_ID_SUFFIX);
-    return document;
-  }
-
-  /**
-   * Make a SAML EntityDescriptor element for the GSA.
-   *
-   * @param entities The SAML EntitiesDescriptor element to put the element in.
-   * @param id The SAML entity ID for the new element.
-   * @return The EntityDescriptor as a DOM element.
-   */
-  private static Element makeGsaEntity(Element entities, String id) {
-    Element entity = makeTopLevelEntity(entities, id, GSA_ENTITY_COMMENT);
-
-    makeRole(entity, SAML_DESCRIPTOR_SP_SSO);
-    makeAssertionConsumer(entity,
-                          SAML_BINDING_HTTP_ARTIFACT,
-                          makeGsaUrl(GSA_HOST_MARKER, GSA_ASSERTION_CONSUMER_PATH));
-
-    makeGoogleOrganization(entity);
-
-    return entity;
-  }
-
-  /**
-   * Make a URL for the GSA.
-   *
-   * @param host The hostname to use.
-   * @param path The URL path.
-   * @return The URL as a string.
-   */
-  private static String makeGsaUrl(String host, String path) {
-    URL url;
-    try {
-      url = new URL(HTTPS_PROTOCOL, host, -1, path);
-    } catch (MalformedURLException e) {
-      throw new IllegalStateException(e);
-    }
-    return url.toString();
-  }
-
-  /**
-   * Make a SAML EntityDescriptor element for the security manager.
-   *
-   * @param entities The SAML EntitiesDescriptor element to put the new element in.
-   * @param id The SAML entity ID for the new element.
-   * @return The EntityDescriptor as a DOM element.
-   */
-  private static Element makeSmEntity(Element entities, String id) {
-    Element entity = makeTopLevelEntity(entities, id, SECMGR_ENTITY_COMMENT);
-    entity.setAttribute(XML_ATTR_ID, SECMGR_ID_FOR_ENTITY);
-
-    makeRole(entity, SAML_DESCRIPTOR_IDP_SSO);
-    makeSingleSignOn(entity, makeSecurityManagerUrl(GSA_HOST_MARKER, SECMGR_SSO_PATH));
-    makeArtifactResolver(entity, makeSecurityManagerUrl(LOCALHOST, SECMGR_ARTIFACT_RESOLVER_PATH));
-
-    makeRole(entity, SAML_DESCRIPTOR_SP_SSO);
-    makeAssertionConsumer(entity,
-                          SAML_BINDING_HTTP_POST,
-                          makeSecurityManagerUrl(GSA_HOST_MARKER, SECMGR_ASSERTION_CONSUMER_PATH));
-    makeAssertionConsumer(entity,
-                          SAML_BINDING_HTTP_ARTIFACT,
-                          makeSecurityManagerUrl(GSA_HOST_MARKER, SECMGR_ASSERTION_CONSUMER_PATH));
-
-    makePdp(entity, makeSecurityManagerUrl(LOCALHOST, SECMGR_AUTHZ_PATH));
-
-    makeGoogleOrganization(entity);
-    return entity;
-  }
-
-  /**
-   * Make a URL for a security manager servlet.
-   *
-   * @param host The hostname to use.
-   * @param servletPath The part of the path that's specific to the servlet.
-   * @return The URL as a string.
-   */
-  private static String makeSecurityManagerUrl(String host, String servletPath) {
-    String path = SECMGR_WEBAPP_PATH + "/" + servletPath;
-    URL url;
-    try {
-      if (LOCALHOST.equals(host)) {
-        url = new URL(HTTP_PROTOCOL, host, path);
-      } else {
-        url = new URL(HTTPS_PROTOCOL, host, path);
-      }
-    } catch (MalformedURLException e) {
-      throw new IllegalStateException(e);
-    }
-    return url.toString();
-  }
-
-  /**
-   * Make a SAML Organization element for Google.
-   *
-   * @param entity The SAML Entity element to put the new element in.
-   * @return The Organization as a DOM element.
-   */
-  private static Element makeGoogleOrganization(Element entity) {
-    Element organization = makeElement(entity, SAML_ORGANIZATION);
-    makeTextElementChild(organization, SAML_ORGANIZATION_NAME, GOOGLE_ORGANIZATION_NAME);
-    makeTextElementChild(organization, SAML_ORGANIZATION_DISPLAY_NAME,
-        GOOGLE_ORGANIZATION_DISPLAY_NAME);
-    makeTextElementChild(organization, SAML_ORGANIZATION_URL, GOOGLE_ORGANIZATION_URL);
-    return organization;
-  }
-
-  /**
-   * Add an external SAML client IdP to a security manager metadata document.  If there is
-   * already an entity with the same ID, it is replaced.
-   *
-   * @param document A security manager metadata document.
-   * @param client A SAML client IdP descriptor.
-   */
-  public static void addIdpEntity(Document document, SamlClientIdp client) {
-    Element clients = getSamlClients(document);
-    if (clients == null) {
-      clients = makeSamlClients(document);
-    }
-    Element entity = makeEntity(clients, client.getId());
-    if (client.hasSso()) {
-      Element role = makeRole(entity, SAML_DESCRIPTOR_IDP_SSO);
-      makeSingleSignOn(entity, client.getUrl());
-      String artifactUrl = normalizeString(client.getArtifactUrl());
-      if (artifactUrl != null) {
-        makeArtifactResolver(entity, artifactUrl);
-      }
-      if (client.getCertificate() != null) {
-        makeKeyDescriptor(role, client.getCertificate());
-      }
-    }
-    if (client.hasPdp()) {
-      makePdp(entity, client.getAuthzServiceUrl());
-    }
-  }
-
-  private static String normalizeString(String s) {
-    if (s == null) {
-      return s;
-    }
-    s = s.trim();
-    return s.isEmpty() ? null : s;
-  }
-
-  /**
-   * Get the SAML EntitiesDescriptor that holds the client entities.
-   *
-   * @param document The SAML metadata document to look in.
-   * @return The EntitiesDescriptor element, or null if no such.
-   */
-  public static Element getSamlClients(Document document) {
-    NodeList nodes =
-        getElementsByQname(document.getDocumentElement(), SAML_DESCRIPTOR_ENTITIES);
-    for (int index = 0; index < nodes.getLength(); index++) {
-      Element element = Element.class.cast(nodes.item(index));
-      if (SECMGR_CLIENTS_ENTITIES_NAME.equals(element.getAttribute(SAML_ATTR_NAME))) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Make an empty SAML EntitiesDescriptor to hold client entities.
-   *
-   * @param document The SAML metadata document to look in.
-   * @return The new EntitiesDescriptor as a DOM element.
-   */
-  private static Element makeSamlClients(Document document) {
-    return makeTopLevelEntities(document.getDocumentElement(),
-        SECMGR_CLIENTS_ENTITIES_NAME, SECMGR_CLIENTS_ENTITIES_COMMENT);
-  }
-
-  /**
-   * Remove the SAML client entities descriptor, if there is one.
-   *
-   * @param document The SAML metadata document to look in.
-   */
-  private static void deleteSamlClients(Document document) {
-    Element oldClients = getSamlClients(document);
-    if (oldClients != null) {
-      oldClients.getParentNode().removeChild(oldClients);
-    }
-    for (Comment comment :
-             findChildComments(
-                 document.getDocumentElement(),
-                 SECMGR_CLIENTS_ENTITIES_COMMENT)) {
-      comment.getParentNode().removeChild(comment);
-    }
-  }
-
-
-  // Endpoint constructors.
-
-  /**
-   * Make a SAML SingleSignOn element.
-   *
-   * @param entity The SAML EntityDescriptor to put the new element in.
-   * @param url The endpoint URL for the new element.
-   * @return The new SingleSignOn as a DOM element.
-   */
-  private static Element makeSingleSignOn(Element entity, String url) {
-    return makeEndpoint(findRole(entity, SAML_DESCRIPTOR_IDP_SSO),
-        SAML_SERVICE_SINGLE_SIGN_ON, SAML_BINDING_HTTP_REDIRECT, url);
-  }
-
-  /**
-   * Make a SAML ArtifactResolver element.
-   *
-   * @param entity The SAML EntityDescriptor to put the new element in.
-   * @param url The endpoint URL for the new element.
-   * @return The new ArtifactResolver as a DOM element.
-   */
-  private static Element makeArtifactResolver(Element entity, String url) {
-    return makeIndexedEndpoint(findRole(entity, SAML_DESCRIPTOR_IDP_SSO),
-        SAML_SERVICE_ARTIFACT_RESOLUTION, SAML_BINDING_SOAP, url);
-  }
-
-  /**
-   * Make a SAML AssertionConsumer element.
-   *
-   * @param entity The SAML EntityDescriptor to put the new element in.
-   * @param url The endpoint URL for the new element.
-   * @return The new AssertionConsumer as a DOM element.
-   */
-  private static Element makeAssertionConsumer(Element entity, String binding, String url) {
-    return makeIndexedEndpoint(findRole(entity, SAML_DESCRIPTOR_SP_SSO),
-        SAML_SERVICE_ASSERTION_CONSUMER, binding, url);
-  }
-
-  /**
-   * Make a SAML PDPDescriptor element.
-   *
-   * @param entity The SAML EntityDescriptor to put the new element in.
-   * @param url The endpoint URL for the new element.
-   * @return The new PDPDescriptor as a DOM element.
-   */
-  private static Element makePdp(Element entity, String url) {
-    Element role = makeRole(entity, SAML_DESCRIPTOR_PDP);
-    makeEndpoint(role, SAML_SERVICE_AUTHZ, SAML_BINDING_SOAP, url);
-    return role;
-  }
-
-  /**
-   * Find a role element with a given name.
-   *
-   * @param entity The SAML EntityDescriptor to look in.
-   * @param qname The qname of the role element to look for.
-   * @return The specified role element.
-   * @throws IllegalArgumentException if there's no such child.
-   */
-  private static Element findRole(Element entity, QName qname) {
-    return findChildElement(entity, qname, true);
-  }
-
-
-  // Element constructors.
-
-  /**
-   * Make a new top-level SAML EntitiesDescriptor element.
-   *
-   * @param entities The SAML EntitiesDescriptor to put the new element in.
-   * @param name The name of the new element -- will be put in the name attribute.
-   * @param comment A descriptive comment that will be added as an XML comment.
-   * @return The new EntitiesDescriptor as a DOM element.
-   */
-  private static Element makeTopLevelEntities(Element entities, String name, String comment) {
-    makeTextChild(entities, "\n");
-    makeCommentChild(entities, " " + comment + " ");
-    makeTextChild(entities, "\n");
-    Element result = makeEntities(entities, name);
-    makeTextChild(entities, "\n");
-    return result;
-  }
-
-  /**
-   * Make a new SAML EntitiesDescriptor element.
-   *
-   * @param entities The SAML EntitiesDescriptor to put the new element in.
-   * @param name The name of the new element -- will be put in the name attribute.
-   * @return The new EntitiesDescriptor as a DOM element.
-   */
-  private static Element makeEntities(Element entities, String name) {
-    Element child = makeElementChild(entities, SAML_DESCRIPTOR_ENTITIES);
-    child.setAttribute(SAML_ATTR_NAME, name);
-    return child;
-  }
-
-  /**
-   * Make a new top-level SAML EntityDescriptor element.
-   *
-   * @param entities The SAML EntitiesDescriptor to put the new element in.
-   * @param id The id of the new element -- will be put in the ID attribute.
-   * @param comment A descriptive comment that will be added as an XML comment.
-   * @return The new EntityDescriptor as a DOM element.
-   */
-  private static Element makeTopLevelEntity(Element entities, String id, String comment) {
-    makeTextChild(entities, "\n");
-    makeCommentChild(entities, " " + comment + " ");
-    makeTextChild(entities, "\n");
-    Element entity = makeEntity(entities, id);
-    makeTextChild(entities, "\n");
-    return entity;
-  }
-
-  /**
-   * Make a new SAML EntityDescriptor element.
-   *
-   * @param entities The SAML EntitiesDescriptor to put the new element in.
-   * @param id The id of the new element -- will be put in the ID attribute.
-   * @return The new EntityDescriptor as a DOM element.
-   */
-  private static Element makeEntity(Element entities, String id) {
-    Element old = findEntity(entities, id);
-    Element entity = makeElement(entities, SAML_DESCRIPTOR_ENTITY);
-    entity.setAttribute(SAML_ATTR_ENTITY_ID, id);
-    if (old == null) {
-      entities.appendChild(entity);
-    } else {
-      entities.replaceChild(entity, old);
-    }
-    return entity;
-  }
-
-  /**
-   * Find a SAML EntityDescriptor element.
-   *
-   * @param entities The SAML EntitiesDescriptor to look in.
-   * @param id The id of the element to look for.
-   * @return The specified EntityDescriptor, or null if no such.
-   */
-  private static Element findEntity(Element entities, String id) {
-    NodeList nodes = getElementsByQname(entities, SAML_DESCRIPTOR_ENTITY);
-    for (int index = 0; index < nodes.getLength(); index++) {
-      Element element = Element.class.cast(nodes.item(index));
-      if (id.equals(element.getAttribute(SAML_ATTR_ENTITY_ID))) {
-        return element;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Make a new SAML role.
-   *
-   * @param entity the SAML EntityDescriptor to put the new role in.
-   * @param qname The qname of the new role.
-   * @return The new role as a DOM element.
-   */
-  private static Element makeRole(Element entity, QName qname) {
-    Element role = makeElementChild(entity, qname);
-    role.setAttribute(SAML_ATTR_PROTOCOL_SUPPORT_ENUMERATION, SAML_PROTOCOL);
-    return role;
-  }
-
-  /**
-   * Make a new SAML endpoint.
-   *
-   * @param role the SAML role to put the new endpoint in.
-   * @param qname The qname of the new endpoint.
-   * @param binding The SAML binding specifier.
-   * @param url The endpoing URL.
-   * @return The new endpoint as a DOM element.
-   */
-  private static Element makeEndpoint(Element role, QName qname, String binding, String url) {
-    Element endpoint = makeElementChild(role, qname);
-    endpoint.setAttribute(SAML_ATTR_BINDING, binding);
-    endpoint.setAttribute(SAML_ATTR_LOCATION, url);
-    return endpoint;
-  }
-
-  /**
-   * Make a new SAML indexed endpoint.
-   *
-   * @param role the SAML role to put the new endpoint in.
-   * @param qname The qname of the new endpoint.
-   * @param binding The SAML binding specifier.
-   * @param url The endpoing URL.
-   * @return The new endpoint as a DOM element.
-   */
-  private static Element makeIndexedEndpoint(
-      Element role, QName qname, String binding, String url) {
-    int nChildren = countChildElements(role, qname);
-    Element endpoint = makeEndpoint(role, qname, binding, url);
-    endpoint.setAttribute(SAML_ATTR_INDEX, Integer.toString(nChildren));
-    endpoint.setAttribute(SAML_ATTR_IS_DEFAULT, (nChildren == 0) ? "true" : "false");
-    return endpoint;
-  }
-
-  /**
-   * Make a new SAML key descriptor.
-   *
-   * @param role the SAML role to put the new descriptor in.
-   * @param certificate The X509 certificate that the descriptor will contain.
-   * @return The new key descriptor as a DOM element.
-   */
-  private static Element makeKeyDescriptor(Element role, String certificate) {
-    Element keyDescriptor = makeElementChild(role, SAML_DESCRIPTOR_KEY);
-    keyDescriptor.setAttribute(SAML_ATTR_USE, SAML_USAGE_SIGNING);
-    Element keyInfo = makeElementChild(keyDescriptor, XMLDSIG_KEY_INFO);
-    Element x509Data = makeElementChild(keyInfo, XMLDSIG_X509_DATA);
-    makeTextElementChild(x509Data, XMLDSIG_X509_CERTIFICATE, normalizeCertificate(certificate));
-    return keyDescriptor;
-  }
-
-  /**
-   * Get the certificate out of a SAML key descriptor.  Works only with key descriptors
-   * created by #makeKeyDescriptor().
-   *
-   * @param keyDescriptor The SAML key descriptor to extract from.
-   * @return The extracted certificate, or null if none such.
-   */
-  private static String keyDescriptorCertificate(Element keyDescriptor) {
-    Element keyInfo = findChildElement(keyDescriptor, XMLDSIG_KEY_INFO, false);
-    if (keyInfo == null) { return null; }
-    Element x509Data = findChildElement(keyInfo, XMLDSIG_X509_DATA, false);
-    if (x509Data == null) { return null; }
-    Element x509Certificate = findChildElement(x509Data, XMLDSIG_X509_CERTIFICATE, false);
-    if (x509Certificate == null) { return null; }
-    NodeList nodes = x509Certificate.getChildNodes();
-    if (nodes.getLength() == 1 && nodes.item(0).getNodeType() == Node.TEXT_NODE) {
-      return normalizeCertificate(nodes.item(0).getNodeValue());
-    }
-    return null;
-  }
-
-  /**
-   * Convert a PEM certificate to normalized form.
-   *
-   * @param s The certificate to normalize.
-   * @return The normalized certificate.
-   */
-  public static String normalizeCertificate(String s) {
-    if (s == null) {
-      return s;
-    }
-    List<String> lines = Lists.newArrayList();
-    for (String line : s.trim().split("\n+")) {
-      lines.add(line.trim());
-    }
-    if (lines.size() == 0) {
-      return null;
-    }
-    // Trim off X509 header/footer if present.
-    if (X509_HEADER.equals(lines.get(0))
-        && X509_FOOTER.equals(lines.get(lines.size() - 1))) {
-      lines.remove(lines.size() - 1);
-      lines.remove(0);
-    }
-    StringBuilder builder = new StringBuilder();
-    for (String line : lines) {
-      builder.append(line);
-      builder.append("\n");
-    }
-    return builder.toString();
-  }
-}
diff --git a/src/com/google/enterprise/secmgr/saml/OpenSamlUtil.java b/src/com/google/enterprise/secmgr/saml/OpenSamlUtil.java
index bb65627..6f822f2 100644
--- a/src/com/google/enterprise/secmgr/saml/OpenSamlUtil.java
+++ b/src/com/google/enterprise/secmgr/saml/OpenSamlUtil.java
@@ -16,14 +16,8 @@
 
 import static org.opensaml.common.xml.SAMLConstants.SAML20P_NS;
 
-import com.google.common.annotations.VisibleForTesting;
 import com.google.common.collect.Lists;
-//import com.google.enterprise.secmgr.authncontroller.AuthnSession;
-import com.google.enterprise.secmgr.common.FileUtil;
-import com.google.enterprise.secmgr.common.HttpUtil;
-import com.google.enterprise.secmgr.config.ConfigSingleton;
 
-//import org.jdom.Namespace;
 import org.joda.time.DateTime;
 import org.opensaml.Configuration;
 import org.opensaml.DefaultBootstrap;
@@ -37,9 +31,7 @@
 import org.opensaml.common.binding.artifact.BasicSAMLArtifactMap;
 import org.opensaml.common.binding.artifact.SAMLArtifactMap;
 import org.opensaml.common.binding.artifact.SAMLArtifactMap.SAMLArtifactMapEntry;
-import org.opensaml.common.binding.security.SAMLProtocolMessageXMLSignatureSecurityPolicyRule;
 import org.opensaml.common.impl.SecureRandomIdentifierGenerator;
-import org.opensaml.saml2.binding.security.SAML2HTTPRedirectDeflateSignatureRule;
 import org.opensaml.saml2.core.Action;
 import org.opensaml.saml2.core.Artifact;
 import org.opensaml.saml2.core.ArtifactResolve;
@@ -109,10 +101,7 @@
 import org.opensaml.xml.security.keyinfo.provider.InlineX509DataProvider;
 import org.opensaml.xml.security.keyinfo.provider.RSAKeyValueProvider;
 import org.opensaml.xml.security.trust.TrustEngine;
-import org.opensaml.xml.security.x509.X509Credential;
 import org.opensaml.xml.signature.KeyInfo;
-import org.opensaml.xml.signature.SignatureTrustEngine;
-import org.opensaml.xml.signature.impl.ExplicitKeySignatureTrustEngine;
 import org.w3c.dom.Element;
 
 import java.io.File;
@@ -120,15 +109,11 @@
 import java.security.KeyException;
 import java.security.NoSuchAlgorithmException;
 import java.security.PrivateKey;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.List;
-import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.annotation.concurrent.Immutable;
-import javax.servlet.http.HttpServletRequest;
 import javax.xml.namespace.QName;
 
 /**
@@ -927,31 +912,6 @@
   }
 
   /**
-   * Run a message decoder.
-   *
-   * @param decoder The message decoder to run.
-   * @param context The message context to pass to the decoder.
-   * @param senderDescription A phrase describing the sender of the message.
-   * @return True only if the message was successfully decode.
-   */
-  /*
-  // Commented out to prevent pulling in AuthnSession.
-  public static boolean runDecoder(MessageDecoder decoder, MessageContext context,
-      AuthnSession session, String senderDescription) {
-    try {
-      decoder.decode(context);
-    } catch (MessageDecodingException e) {
-      LOGGER.warning(session.logMessage("Unable to decode SAML message from " + senderDescription));
-      return false;
-    } catch (SecurityException e) {
-      LOGGER.warning(session.logMessage("Unable to verify signature of SAML message from " +
-              senderDescription));
-      return false;
-    }
-    return true;
-  }*/
-
-  /**
    * Get a string for the current date/time, in the correct format for SAML.
    *
    * @return The corresponding string.
@@ -1024,50 +984,6 @@
     return securityPolicy;
   }
 
-  /**
-   * Get a signature policy rule for XML signatures, using metadata credentials.
-   *
-   * @param request An HTTP request to use for specializing the metadata.
-   * @return An appropriate signature policy rule.
-   * @throws IOException
-   */
-  public static synchronized SecurityPolicyRule getMetadataSignaturePolicyRule(
-      HttpServletRequest request)
-      throws IOException {
-    return new SAMLProtocolMessageXMLSignatureSecurityPolicyRule(
-        getMetadataSignatureTrustEngine(request));
-  }
-
-  /**
-   * Get a signature policy rule for the redirect binding, using metadata credentials.
-   *
-   * @param request An HTTP request to use for specializing the metadata.
-   * @return An appropriate signature policy rule.
-   * @throws IOException
-   */
-  public static synchronized SecurityPolicyRule getMetadataSignaturePolicyRuleForRedirect(
-      HttpServletRequest request)
-      throws IOException {
-    return new SAML2HTTPRedirectDeflateSignatureRule(
-        getMetadataSignatureTrustEngine(request));
-  }
-
-  /**
-   * Make a trust engine that checks signatures using credentials in metadata.
-   *
-   * @param request An HTTP request to use for specializing the metadata.
-   * @return An appropriate signature trust engine.
-   * @throws IOException
-   */
-  public static SignatureTrustEngine getMetadataSignatureTrustEngine(HttpServletRequest request)
-      throws IOException {
-    KeyInfoCredentialResolver keyInfoCredentialResolver = getStandardKeyInfoCredentialResolver();
-    MetadataCredentialResolver credentialResolver =
-        new MetadataCredentialResolver(getMetadata(request).getProvider());
-    credentialResolver.setKeyInfoCredentialResolver(keyInfoCredentialResolver);
-    return new ExplicitKeySignatureTrustEngine(credentialResolver, keyInfoCredentialResolver);
-  }
-
   private static KeyInfoCredentialResolver standardKeyInfoCredentialResolver = null;
 
   /**
@@ -1123,40 +1039,6 @@
   }
 
   /**
-   * Read a PEM-encoded X.509 certificate file and its associated private-key file and
-   * return an {@link X509Credential} object.
-   *
-   * @param certFile The certificate file.
-   * @param keyFile The private-key file.
-   * @return The credential object, never null.
-   * @throws IOException if there's some kind of error reading or converting the files.
-   */
-  public static X509Credential readX509Credential(File certFile, File keyFile)
-      throws IOException {
-    return SecurityHelper.getSimpleCredential(
-        readX509CertificateFile(certFile),
-        readPrivateKeyFile(keyFile));
-  }
-
-  /**
-   * Read a PEM-encoded X.509 certificate file and return it as an {@link X509Certificate}
-   * object.
-   *
-   * @param file The file to read.
-   * @return The certificate object, never null.
-   * @throws IOException if there's some kind of error reading or converting the file.
-   */
-  public static X509Certificate readX509CertificateFile(File file)
-      throws IOException {
-    String base64Cert = FileUtil.readPEMCertificateFile(file);
-    try {
-      return SecurityHelper.buildJavaX509Cert(base64Cert);
-    } catch (CertificateException e) {
-      throw new IOException(e);
-    }
-  }
-
-  /**
    * Read a PEM-encoded private-key file and return it as a {@link PrivateKey} object.
    *
    * @param file The file to read.
@@ -1206,87 +1088,4 @@
         new MapBasedStorageService<String, SAMLArtifactMapEntry>(),
         artifactLifetime);
   }
-
-  /**
-   * Gets an entity descriptor with a given ID.
-   *
-   * @param id The ID of the entity to get.
-   * @param request The servlet request to use for getting the metadata.
-   * @return The entity's descriptor, or {@code null} if there's no entity with
-   *     that ID.
-   */
-  public static EntityDescriptor getEntity(String id, HttpServletRequest request)
-      throws IOException {
-    return getMetadata(request).getEntity(id);
-  }
-
-  /**
-   * Gets the entity descriptor for the security manager.
-   *
-   * @param request The servlet request to use for getting the metadata.
-   * @return The security manager's entity descriptor.
-   */
-  public static EntityDescriptor getSmEntity(HttpServletRequest request)
-      throws IOException {
-    return getMetadata(request).getSmEntity();
-  }
-
-  /**
-   * Gets the entity ID for the security manager.
-   *
-   * @param request The servlet request to use for getting the metadata.
-   * @return The security manager's entity ID.
-   */
-  public static String getSmEntityId(HttpServletRequest request)
-      throws IOException {
-    return getMetadata(request).getSmEntityId();
-  }
-
-  /**
-   * Gets the SAML metadata.
-   *
-   * @param request The servlet request to use for customizing the metadata.
-   * @return The metadata.
-   */
-  public static Metadata getMetadata(HttpServletRequest request)
-      throws IOException {
-    return Metadata.getInstance(HttpUtil.getRequestUrl(request, false));
-  }
-
-  @VisibleForTesting
-  public static Metadata getMetadata()
-      throws IOException {
-    return Metadata.getInstance("localhost");
-  }
-
-  /**
-   * Gets the credential to use for signing outgoing messages.
-   *
-   * @return The credential, or null if unable to obtain.
-   */
-  public static Credential getSigningCredential()
-      throws IOException {
-    String certFileName = ConfigSingleton.getSigningCertificateFilename();
-    String keyFileName = ConfigSingleton.getSigningKeyFilename();
-    if (certFileName == null || keyFileName == null) {
-      LOGGER.info("No signing certificate available for outbound requests");
-      return null;
-    }
-    File certFile = FileUtil.getContextFile(certFileName);
-    File keyFile = FileUtil.getContextFile(keyFileName);
-    if (!certFile.canRead()) {
-      LOGGER.warning("Unable to read signing certificate file: " + certFile);
-      return null;
-    }
-    if (!keyFile.canRead()) {
-      LOGGER.warning("Unable to read signing key file: " + keyFile);
-      return null;
-    }
-    try {
-      return OpenSamlUtil.readX509Credential(certFile, keyFile);
-    } catch (IOException e) {
-      LOGGER.log(Level.WARNING, "Error reading certificate file(s): ", e);
-      return null;
-    }
-  }
 }
diff --git a/src/com/google/enterprise/secmgr/servlets/ResponseParser.java b/src/com/google/enterprise/secmgr/servlets/ResponseParser.java
index 3d82d21..93db806 100644
--- a/src/com/google/enterprise/secmgr/servlets/ResponseParser.java
+++ b/src/com/google/enterprise/secmgr/servlets/ResponseParser.java
@@ -21,7 +21,6 @@
 import com.google.common.collect.Iterables;
 import com.google.enterprise.secmgr.authncontroller.ExportedState;
 import com.google.enterprise.secmgr.common.SecurityManagerUtil;
-import com.google.enterprise.secmgr.identity.Verification;
 import com.google.enterprise.secmgr.modules.SamlClient;
 import com.google.enterprise.secmgr.saml.OpenSamlUtil;
 import com.google.enterprise.secmgr.saml.SamlLogUtil;
@@ -209,21 +208,6 @@
   }
 
   /**
-   * Convert an assertion's expiration time to a form suitable for use in a
-   * verification.
-   *
-   * @param time The given expiration time.
-   * @return An expiration time usable by a verification.
-   */
-  public long expirationTimeToVerificationTime(DateTime time) {
-    if (time != null) {
-      return time.getMillis();
-    }
-    warn("SAML IdP failed to return expiration time");
-    return Verification.NEVER_EXPIRES;
-  }
-
-  /**
    * Gets an exported-state object.  This information is a security manager
    * extension.  Must satisfy {@link #areAssertionsValid} prior to calling.
    */
diff --git a/src/com/google/inject/Inject.java b/src/com/google/inject/Inject.java
deleted file mode 100644
index 92da74e..0000000
--- a/src/com/google/inject/Inject.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.inject;
-
-/**
- * Mock Inject.
- */
-public @interface Inject {}
diff --git a/src/com/google/inject/Injector.java b/src/com/google/inject/Injector.java
deleted file mode 100644
index 9495d19..0000000
--- a/src/com/google/inject/Injector.java
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.inject;
-
-/**
- * Mock Injector.
- */
-public class Injector {
-  public <T> T getInstance(Class<T> clazz) {
-    throw new UnsupportedOperationException();
-  }
-
-  public <T> T getInstance(Key<T> key) {
-    throw new UnsupportedOperationException();
-  }
-}
diff --git a/src/com/google/inject/Key.java b/src/com/google/inject/Key.java
deleted file mode 100644
index be051ff..0000000
--- a/src/com/google/inject/Key.java
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.inject;
-
-/**
- * Mock Key.
- */
-public class Key<T> {
-  public static <T> Key<T> get(TypeLiteral<T> type) {
-    throw new UnsupportedOperationException();
-  }
-}
diff --git a/src/com/google/inject/Singleton.java b/src/com/google/inject/Singleton.java
deleted file mode 100644
index 0a998f5..0000000
--- a/src/com/google/inject/Singleton.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.inject;
-
-/**
- * Mock Singleton.
- */
-public @interface Singleton {}
diff --git a/src/com/google/inject/TypeLiteral.java b/src/com/google/inject/TypeLiteral.java
deleted file mode 100644
index 326d6d7..0000000
--- a/src/com/google/inject/TypeLiteral.java
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.inject;
-
-/**
- * Mock TypeLiteral.
- */
-public class TypeLiteral<T> {}
diff --git a/src/com/google/inject/name/Named.java b/src/com/google/inject/name/Named.java
deleted file mode 100644
index 41ea9b9..0000000
--- a/src/com/google/inject/name/Named.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.inject.name;
-
-/**
- * Mock Named.
- */
-public @interface Named {
-  String value();
-}
diff --git a/src/org/springframework/mock/web/MockHttpServletRequest.java b/src/org/springframework/mock/web/MockHttpServletRequest.java
deleted file mode 100644
index 1bef3a7..0000000
--- a/src/org/springframework/mock/web/MockHttpServletRequest.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright 2011 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package org.springframework.mock.web;
-
-import javax.servlet.http.HttpServletRequest;
-
-/**
- * Mock of a mock
- */
-public interface MockHttpServletRequest extends HttpServletRequest {}
diff --git a/test/com/google/enterprise/adaptor/CronSchedulerTest.java b/test/com/google/enterprise/adaptor/CronSchedulerTest.java
index e0be115..68414a6 100644
--- a/test/com/google/enterprise/adaptor/CronSchedulerTest.java
+++ b/test/com/google/enterprise/adaptor/CronSchedulerTest.java
@@ -51,8 +51,10 @@
         scheduler.schedule("0 0 1 1 1-7/2", noopRunnable).toString());
     assertEquals("CronFuture([{0}, {0}, {1, 3, 5, 7, 9, 11}, {0}, {0}])",
         scheduler.schedule("0 0 2-13/2 1 0", noopRunnable).toString());
-    assertEquals("CronFuture([{0}, {0}, {0}, {0}, {0, 1, 2, 3, 4, 5, 6}])",
+    assertEquals("CronFuture([{0}, {0}, {0}, {0}, null])",
         scheduler.schedule("0 0 1 1 *", noopRunnable).toString());
+    assertEquals("CronFuture([{0}, {0}, {0}, {0}, {0, 1, 2, 3, 4, 5, 6}])",
+        scheduler.schedule("0 0 1 1 */1", noopRunnable).toString());
   }
 
   @Test
@@ -152,46 +154,61 @@
     // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
     timeProvider.time = 2800921L * 1000;
     atomicCommand.get().run();
-    Thread.sleep(10);
     assertEquals(1, counter.get());
 
     // Wrong minute.
     // 1970-02-02T10:01:01Z, which is a Monday. That is 02:01:01 in PST.
     timeProvider.time = 2800861L * 1000;
     atomicCommand.get().run();
-    Thread.sleep(10);
     assertEquals(1, counter.get());
 
     // Wrong hour.
     // 1970-02-02T09:02:01Z, which is a Monday. That is 01:02:01 in PST.
     timeProvider.time = 2797321L * 1000;
     atomicCommand.get().run();
-    Thread.sleep(10);
     assertEquals(1, counter.get());
 
     // Wrong day of month.
     // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
     timeProvider.time = 2800921L * 1000;
-    scheduler.reschedule(future, "2 2 1 2 2");
+    scheduler.reschedule(future, "2 2 1 2 *");
     atomicCommand.get().run();
-    Thread.sleep(10);
     assertEquals(1, counter.get());
 
     // Wrong month.
     // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
     timeProvider.time = 2800921L * 1000;
-    scheduler.reschedule(future, "2 2 2 1 2");
+    scheduler.reschedule(future, "2 2 2 1 1");
     atomicCommand.get().run();
-    Thread.sleep(10);
     assertEquals(1, counter.get());
 
     // Wrong day of week.
     // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
     timeProvider.time = 2800921L * 1000;
+    scheduler.reschedule(future, "2 2 * 2 2");
+    atomicCommand.get().run();
+    assertEquals(1, counter.get());
+
+    // Wrong day of week and day of month.
+    // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
+    timeProvider.time = 2800921L * 1000;
+    scheduler.reschedule(future, "2 2 1 2 2");
+    atomicCommand.get().run();
+    assertEquals(1, counter.get());
+
+    // Wrong day of week, but right day of month.
+    // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
+    timeProvider.time = 2800921L * 1000;
     scheduler.reschedule(future, "2 2 2 2 2");
     atomicCommand.get().run();
-    Thread.sleep(10);
-    assertEquals(1, counter.get());
+    assertEquals(2, counter.get());
+
+    // Wrong day of month, but right day of week.
+    // 1970-02-02T10:02:01Z, which is a Monday. That is 02:02:01 in PST.
+    timeProvider.time = 2800921L * 1000;
+    scheduler.reschedule(future, "2 2 1 2 1");
+    atomicCommand.get().run();
+    assertEquals(3, counter.get());
   }
 
   @Test
diff --git a/test/com/google/enterprise/adaptor/HttpClientAdapterTest.java b/test/com/google/enterprise/adaptor/HttpClientAdapterTest.java
deleted file mode 100644
index 21db551..0000000
--- a/test/com/google/enterprise/adaptor/HttpClientAdapterTest.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.enterprise.adaptor;
-
-import static org.junit.Assert.*;
-
-import org.junit.*;
-import org.junit.rules.ExpectedException;
-
-/**
- * Test cases for {@link HttpClientAdapter}.
- */
-public class HttpClientAdapterTest {
-  @Rule
-  public ExpectedException thrown = ExpectedException.none();
-
-  private HttpClientAdapter httpClient = new HttpClientAdapter();
-
-  @Test
-  public void testHeadExchange() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.headExchange(null);
-  }
-
-  @Test
-  public void testGetExchange() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.getExchange(null);
-  }
-
-  @Test
-  public void testNewHttpExchange() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.newHttpExchange(null);
-  }
-
-  @Test
-  public void testGetConnection() throws Exception {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.getConnection(null);
-  }
-
-  @Test
-  public void testHeadExchange2() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.headExchange(null, null);
-  }
-
-  @Test
-  public void testGetExchange2() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.getExchange(null, null);
-  }
-
-  @Test
-  public void testPostExchange3() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.postExchange(null, null, null);
-  }
-
-  @Test
-  public void testNewHttpExchange2() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.newHttpExchange(null, null);
-  }
-
-  @Test
-  public void testSetRequestTimeoutMillis() {
-    thrown.expect(UnsupportedOperationException.class);
-    httpClient.setRequestTimeoutMillis(-1);
-  }
-}
diff --git a/test/com/google/enterprise/adaptor/MockHttpClient.java b/test/com/google/enterprise/adaptor/MockHttpClient.java
index ab3f35f..734f260 100644
--- a/test/com/google/enterprise/adaptor/MockHttpClient.java
+++ b/test/com/google/enterprise/adaptor/MockHttpClient.java
@@ -15,8 +15,6 @@
 package com.google.enterprise.adaptor;
 
 import com.google.common.collect.ListMultimap;
-import com.google.enterprise.secmgr.common.CookieStore;
-import com.google.enterprise.secmgr.common.GCookie;
 import com.google.enterprise.secmgr.http.HttpClientInterface;
 import com.google.enterprise.secmgr.http.HttpExchange;
 
@@ -36,16 +34,6 @@
   protected abstract void handleExchange(ClientExchange ex);
 
   @Override
-  public HttpExchange headExchange(URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange getExchange(URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
   public HttpExchange postExchange(URL url,
                                    ListMultimap<String, String> parameters) {
     HttpExchange exchange = new ClientExchange(url, "POST");
@@ -61,42 +49,6 @@
     return exchange;
   }
 
-  @Override
-  public HttpExchange newHttpExchange(URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public Connection getConnection(URL url) throws IOException {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange headExchange(Connection connection, URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange getExchange(Connection connection, URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange postExchange(Connection connection, URL url,
-                                   ListMultimap<String, String> parameters) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public HttpExchange newHttpExchange(Connection connection, URL url) {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void setRequestTimeoutMillis(int millisec) {
-    throw new UnsupportedOperationException();
-  }
-
   /** Mocked exchange that calls {@link #handleExchange}. */
   protected class ClientExchange implements HttpExchange {
     private final URL url;
@@ -173,16 +125,6 @@
       return requestHeaders.getFirst(headerName);
     }
 
-    @Override
-    public void addCookies(Iterable<GCookie> cookies) {
-      throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CookieStore getCookies() {
-      throw new UnsupportedOperationException();
-    }
-
     /** Does not copy provided byte array. */
     @Override
     public void setRequestBody(byte[] byteArrayRequestEntity) {
diff --git a/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java b/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java
index 8b67eba..56d0bcb 100644
--- a/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java
+++ b/test/com/google/enterprise/adaptor/SamlIdentityProviderTest.java
@@ -92,8 +92,11 @@
     assertTrue(samlResponse.contains("https://entyo36.hot.corp.google.com/"
         + "security-manager/samlassertionconsumer"));
     assertTrue(samlResponse.contains("user1"));
-    assertTrue(samlResponse.contains("group1"));
-    assertTrue(samlResponse.contains("group2"));
+    assertTrue(samlResponse.contains(
+        "<saml2:AttributeStatement><saml2:Attribute Name=\"member-of\">"
+        + "<saml2:AttributeValue>group1</saml2:AttributeValue>"
+        + "<saml2:AttributeValue>group2</saml2:AttributeValue>"
+        + "</saml2:Attribute></saml2:AttributeStatement>"));
   }
 
   @Test
