diff --git a/src/com/google/enterprise/adaptor/ad/AdEntity.java b/src/com/google/enterprise/adaptor/ad/AdEntity.java
index 3697849..2f71440 100644
--- a/src/com/google/enterprise/adaptor/ad/AdEntity.java
+++ b/src/com/google/enterprise/adaptor/ad/AdEntity.java
@@ -1,10 +1,9 @@
 package com.google.enterprise.adaptor.ad;
 
-import java.util.logging.Logger;
-import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Map;
 import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Pattern;
 
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
@@ -12,6 +11,7 @@
 import javax.naming.directory.Attributes;
 import javax.naming.directory.SearchResult;
 
+/** Representation of a single user or group from Active Directory. */
 public class AdEntity {
   private static final Logger log =
       Logger.getLogger(AdEntity.class.getName());
@@ -26,6 +26,8 @@
   private long uSNChanged;
   private boolean wellKnown;
   private boolean allMembershipsRetrieved;
+  private final Pattern attrMemberPattern =
+      Pattern.compile("member;range=[0-9]+-.*", Pattern.CASE_INSENSITIVE);
 
   private Object getAttribute(Attributes attributes, String name)
       throws NamingException {
@@ -39,7 +41,7 @@
 
   private Attribute getMemberAttr(Attributes attrs) throws NamingException {
     allMembershipsRetrieved = true;
-    Attribute member = attrs.get(AdConstants.ATTR_MEMBER);
+    Attribute member = attrs.get("member");
     if (member != null && member.size() != 0) {
       return member;
     }
@@ -47,7 +49,7 @@
     NamingEnumeration<String> ids = attrs.getIDs();
     while (ids.hasMore()) {
       String id = ids.next();
-      if (AdConstants.ATTR_MEMBER_PATTERN.matcher(id).matches()) {
+      if (attrMemberPattern.matcher(id).matches()) {
         allMembershipsRetrieved = id.endsWith("*");
         return attrs.get(id);
       }
@@ -66,18 +68,15 @@
     dn = searchResult.getNameInNamespace();
     wellKnown = false;
     Attributes attrs = searchResult.getAttributes();
-    sAMAccountName =
-        (String) getAttribute(attrs, AdConstants.ATTR_SAMACCOUNTNAME);
-    objectGUID =
-        getTextGuid((byte[]) getAttribute(attrs, AdConstants.ATTR_OBJECTGUID));
-    sid = getTextSid((byte[]) getAttribute(attrs, AdConstants.ATTR_OBJECTSID));
-    String s = (String) getAttribute(attrs, AdConstants.ATTR_USNCHANGED);
+    sAMAccountName = (String) getAttribute(attrs, "sAMAccountName");
+    objectGUID = getTextGuid((byte[]) getAttribute(attrs, "objectGUID;binary"));
+    sid = getTextSid((byte[]) getAttribute(attrs, "objectSid;binary"));
+    String s = (String) getAttribute(attrs, "uSNChanged");
     if (s != null) {
       uSNChanged = Long.parseLong(s);
     }
-    primaryGroupId =
-        (String) getAttribute(attrs, AdConstants.ATTR_PRIMARYGROUPID);
-    userPrincipalName = (String) getAttribute(attrs, AdConstants.ATTR_UPN);
+    primaryGroupId = (String) getAttribute(attrs, "primaryGroupId");
+    userPrincipalName = (String) getAttribute(attrs, "userPrincipalName");
 
     members = new HashSet<String>();
     if (isGroup()) {
@@ -106,19 +105,19 @@
   }
 
   /**
-   * Appends additional memberships from search result 
+   * Appends additional memberships from search result
    * @param searchResult which contains additional groups
    * @return number of groups found
    * @throws NamingException
    */
   public int appendGroups(SearchResult searchResult)
       throws NamingException {
-    Attribute member = getMemberAttr(searchResult.getAttributes()); 
+    Attribute member = getMemberAttr(searchResult.getAttributes());
     if (member != null) {
       for (int i = 0; i < member.size(); ++i) {
         members.add(member.get(i).toString());
       }
-      return member.size(); 
+      return member.size();
     } else {
       return 0;
     }
@@ -133,17 +132,13 @@
   public String getCommonName() {
     // LDAP queries return escaped commas to avoid ambiguity, find first not
     // escaped comma
-    int comma = dn.indexOf(AdConstants.COMMA);
-    while (comma > 0 && comma < dn.length()
-        && (dn.charAt(comma - 1) == AdConstants.BACKSLASH_CHAR)) {
-      comma = dn.indexOf(AdConstants.COMMA, comma + 1);
+    int comma = dn.indexOf(",");
+    while (comma > 0 && dn.charAt(comma - 1) == '\\') {
+      comma = dn.indexOf(",", comma + 1);
     }
     String tmpGroupName = dn.substring(0, comma > 0 ? comma : dn.length());
-    tmpGroupName =
-        tmpGroupName.substring(
-        tmpGroupName.indexOf(AdConstants.EQUALS_CHAR) + 1);
-    tmpGroupName =
-        tmpGroupName.replace(AdConstants.BACKSLASH, AdConstants.EMPTY);
+    tmpGroupName = tmpGroupName.substring(tmpGroupName.indexOf('=') + 1);
+    tmpGroupName = tmpGroupName.replace("\\", "");
     return tmpGroupName;
   }
 
@@ -158,7 +153,7 @@
     if (objectSid == null) {
       return null;
     }
-    StringBuilder strSID = new StringBuilder(AdConstants.SID_START);
+    StringBuilder strSID = new StringBuilder("S-");
     long version = objectSid[0];
     strSID.append(Long.toString(version));
     long authority = objectSid[4];
@@ -167,7 +162,7 @@
       authority <<= 8;
       authority += objectSid[4 + i] & 0xFF;
     }
-    strSID.append(AdConstants.HYPHEN_CHAR).append(Long.toString(authority));
+    strSID.append('-').append(Long.toString(authority));
     long count = objectSid[2];
     count <<= 8;
     count += objectSid[1] & 0xFF;
@@ -179,34 +174,12 @@
         rid <<= 8;
         rid += objectSid[11 - k + (j * 4)] & 0xFF;
       }
-      strSID.append(AdConstants.HYPHEN_CHAR).append(Long.toString(rid));
+      strSID.append('-').append(Long.toString(rid));
     }
     return strSID.toString();
   }
 
   /**
-   * Generate properties to be used for parameter binding in JDBC
-   * @return map of names and properties of current object
-   */
-  public Map<String, Object> getSqlParams() {
-    HashMap<String, Object> map = new HashMap<String, Object>();
-    map.put(AdConstants.DB_DN, dn);
-    map.put(AdConstants.DB_SAMACCOUNTNAME, sAMAccountName.toLowerCase());
-    map.put(AdConstants.DB_UPN, userPrincipalName);
-    map.put(AdConstants.DB_PRIMARYGROUPID, primaryGroupId);
-    if (sid != null) {
-      map.put(AdConstants.DB_DOMAINSID,
-          sid.substring(0, sid.lastIndexOf(AdConstants.HYPHEN_CHAR)));
-      map.put(AdConstants.DB_RID,
-          sid.substring(sid.lastIndexOf(AdConstants.HYPHEN_CHAR) + 1));
-    }
-    map.put(AdConstants.DB_OBJECTGUID, objectGUID);
-    map.put(AdConstants.DB_USNCHANGED, uSNChanged);
-    map.put(AdConstants.DB_WELLKNOWN, wellKnown ? 1 : 0);
-    return map;
-  }
-
-  /**
    * Parses the binary GUID retrieved from LDAP and converts to textual
    * representation. Text version is used to avoid dealing with different
    * BLOB types between databases.
@@ -214,7 +187,7 @@
    * @return string containing the GUID
    */
   public static String getTextGuid(byte[] binaryGuid) {
-    StringBuilder sb = new StringBuilder(AdConstants.GUID_START);
+    StringBuilder sb = new StringBuilder("0x");
     for (byte b : binaryGuid) {
       sb.append(Integer.toHexString(b & 0xFF));
     }
@@ -253,7 +226,7 @@
   public boolean isGroup() {
     return primaryGroupId == null;
   }
-  
+
   public boolean isWellKnown() {
     return wellKnown;
   }
@@ -270,7 +243,7 @@
   }
 
   public String getPrimaryGroupSid() {
-    int index = sid.lastIndexOf(AdConstants.HYPHEN_CHAR) + 1;
+    int index = sid.lastIndexOf('-') + 1;
     return sid.substring(0,  index) + primaryGroupId;
   }
 
diff --git a/test/com/google/enterprise/adaptor/ad/AdEntityTest.java b/test/com/google/enterprise/adaptor/ad/AdEntityTest.java
new file mode 100644
index 0000000..cfca6d4
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/ad/AdEntityTest.java
@@ -0,0 +1,132 @@
+// Copyright 2013 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.ad;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+import java.util.*;
+
+import javax.naming.directory.*;
+
+/** Test cases for {@link AdEntity}. */
+public class AdEntityTest {
+  @Test
+  public void testStandardConstructor() throws Exception {
+    Attributes attrs = new BasicAttributes();
+    attrs.put("objectGUID;binary",
+        AdServerTest.hexStringToByteArray("000102030405060708090a0b0c"));
+    attrs.put("objectSid;binary", // S-1-0-0
+        AdServerTest.hexStringToByteArray("010100000000000000000000"));
+    attrs.put("uSNChanged", "12345678");
+    attrs.put("primaryGroupId", "users");
+
+    SearchResult sr = new SearchResult("SR name", attrs, attrs);
+    sr.setNameInNamespace("cn=user,ou=Users,dc=example,dc=com");
+    AdEntity adEntity = new AdEntity(sr);
+    assertEquals("user", adEntity.getCommonName());
+    assertEquals("S-1-0-0", adEntity.getSid());
+    assertEquals("cn=user,ou=Users,dc=example,dc=com", adEntity.getDn());
+    assertFalse(adEntity.isWellKnown());
+    assertEquals(0, adEntity.getMembers().size());
+    assertEquals("S-1-0-users", adEntity.getPrimaryGroupSid());
+  }
+
+  @Test
+  public void testWellKnownConstructor() throws Exception {
+    AdEntity adEntity = new AdEntity("S-1-1-1",
+        "dn=escaped\\,cn=users,ou=Users,dc=example,dc=com");
+    assertEquals("escaped,cn=users", adEntity.getCommonName());
+    assertEquals("S-1-1-1", adEntity.getSid());
+    assertEquals("dn=escaped\\,cn=users,ou=Users,dc=example,dc=com",
+        adEntity.getDn());
+    assertTrue(adEntity.isWellKnown());
+    assertEquals(0, adEntity.getMembers().size());
+  }
+
+  @Test
+  public void testWellKnownConstructorNoCommaInDN() throws Exception {
+    AdEntity adEntity = new AdEntity("NoComma", "dc=com");
+    assertEquals("com", adEntity.getCommonName());
+    assertEquals("dc=com", adEntity.getDn());
+    assertTrue(adEntity.isWellKnown());
+  }
+
+  @Test
+  public void testWellKnownConstructorTrailingComma() throws Exception {
+    AdEntity adEntity = new AdEntity("NoComma", "dc=com,");
+    assertEquals("com", adEntity.getCommonName());
+    assertEquals("dc=com,", adEntity.getDn());
+    assertTrue(adEntity.isWellKnown());
+  }
+
+  @Test
+  public void testAppendGroupsOnEmptyGroup() throws Exception {
+    AdEntity adEntity = new AdEntity("parentGroup", "dc=com");
+
+    Attributes attrs = new BasicAttributes();
+    attrs.put("objectGUID;binary",
+        AdServerTest.hexStringToByteArray("000102030405060708090a0b0c"));
+    attrs.put("objectSid;binary", // S-1-0-0
+        AdServerTest.hexStringToByteArray("010100000000000000000000"));
+    attrs.put("member", null);
+    Attribute memberAttr = attrs.get("member");
+    memberAttr.clear();
+    SearchResult sr = new SearchResult("subgroup", attrs, attrs);
+    sr.setNameInNamespace("cn=subgroup,ou=Groups,dc=example,dc=com");
+    AdEntity ae = new AdEntity(sr);
+
+    HashSet<String> expectedMembers = new HashSet<String>();
+    assertEquals(expectedMembers, ae.getMembers());
+    assertEquals(0, adEntity.appendGroups(sr));
+  }
+
+  @Test
+  public void testAppendGroupsOnRealGroup() throws Exception {
+    AdEntity adEntity = new AdEntity("parentGroup", "dc=com");
+
+    Attributes attrs = new BasicAttributes();
+    attrs.put("objectGUID;binary",
+        AdServerTest.hexStringToByteArray("000102030405060708090a0b0c"));
+    attrs.put("objectSid;binary", // S-1-0-0
+        AdServerTest.hexStringToByteArray("010100000000000000000000"));
+    List<String> members = Arrays.asList("dn_for_user_1", "dn_for_user_2");
+    attrs.put("member", null);
+    Attribute memberAttr = attrs.get("member");
+    memberAttr.clear();
+    for (String member: members) {
+      memberAttr.add(member);
+    }
+
+    SearchResult sr = new SearchResult("subgroup", attrs, attrs);
+    sr.setNameInNamespace("cn=subgroup,ou=Groups,dc=example,dc=com");
+    AdEntity ae = new AdEntity(sr);
+
+    assertEquals(new HashSet<String>(members), ae.getMembers());
+    assertEquals(2, adEntity.appendGroups(sr));
+  }
+
+  @Test
+  public void testParseForeignSecurityPrincipal() throws Exception {
+    AdEntity adEntity = new AdEntity("NoComma", "dc=com");
+    assertNull(adEntity.parseForeignSecurityPrincipal(""));
+    assertNull(adEntity.parseForeignSecurityPrincipal(
+        "cn=foreignsecurityprincipals,dc=example,dc=com"));
+    String validSid = "S-1-5-21-42";
+    assertEquals(validSid, adEntity.parseForeignSecurityPrincipal(
+        "id=" + validSid + ",cn=foreignsecurityprincipals,dc=example,dc=com"));
+  }
+}
