Massive removal of SecMgr dead code

This makes it much more obvious what SecMgr code we are actually using.
We limit ourselves to mainly deletes and small changes, because we don't
yet want to fork ourselves too much.
diff --git a/build.xml b/build.xml
index 95b058c..1d8f825 100644
--- a/build.xml
+++ b/build.xml
@@ -76,7 +76,6 @@
     <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"/>
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/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/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/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