Simplify AttributeReference with optional subattribute instead of parent attribute
diff --git a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java
index ff924cb..3c4e24b 100644
--- a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java
+++ b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/provider/UpdateRequest.java
@@ -456,14 +456,13 @@
                                              FilterExpression valueFilterExpression, List<String> subAttributes, Object value) {
     PatchOperation operation = new PatchOperation();
     operation.setOperation(patchOpType);
-    String attribute = attributeReferenceList.size() > 1 ? attributeReferenceList.get(1) : attributeReferenceList.get(0);
-    String parent = attributeReferenceList.size() > 1 ? attributeReferenceList.get(0) : null;
+    String attribute = attributeReferenceList.get(0);
+    String subAttribute = attributeReferenceList.size() > 1 ? attributeReferenceList.get(1) : null;
 
-    if (parent == null && !subAttributes.isEmpty()) {
-      parent = attribute;
-      attribute = subAttributes.get(0);
+    if (subAttribute == null && !subAttributes.isEmpty()) {
+      subAttribute = subAttributes.get(0);
     }
-    AttributeReference attributeReference = new AttributeReference(parseData.pathUri, parent, attribute);
+    AttributeReference attributeReference = new AttributeReference(parseData.pathUri, attribute, subAttribute);
     PatchOperationPath patchOperationPath = new PatchOperationPath();
     ValuePathExpression valuePathExpression = new ValuePathExpression(attributeReference, valueFilterExpression);
     patchOperationPath.setValuePathExpression(valuePathExpression);
diff --git a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/utility/AttributeUtil.java b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/utility/AttributeUtil.java
index 7d03a09..f3f6ba7 100644
--- a/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/utility/AttributeUtil.java
+++ b/scim-server/scim-server-common/src/main/java/edu/psu/swe/scim/server/utility/AttributeUtil.java
@@ -321,30 +321,25 @@
     if (attributeContainer == null) {
       return Collections.emptySet();
     }
-    String parentAttributeName = attributeReference.getParent();
-    String attributeName = attributeReference.getAttributeName();
     Set<Attribute> attributes = new HashSet<>();
+    String attributeName = attributeReference.getAttributeName();
+    String subAttributeName = attributeReference.getSubAttributeName();
+    Attribute attribute = attributeContainer.getAttribute(attributeName);
 
-    if (parentAttributeName != null) {
-      attributeContainer = attributeContainer.getAttribute(parentAttributeName);
-
-      if (attributeContainer == null) {
-        return Collections.emptySet();
-      }
-      if (includeAttributeChain) {
-        Attribute attribute = (Attribute) attributeContainer;
-        attributes.add(attribute);
-      }
-    }
-    attributeContainer = attributeContainer.getAttribute(attributeName);
-
-    if (attributeContainer == null) {
+    if (attribute == null) {
       return Collections.emptySet();
     }
-    Attribute attribute = (Attribute) attributeContainer;
+    if (includeAttributeChain || subAttributeName == null) {
+      attributes.add(attribute);
+    }
+    if (subAttributeName != null) {
+      attribute = attribute.getAttribute(subAttributeName);
 
-    attributes.add(attribute);
-
+      if (attribute == null) {
+        return Collections.emptySet();
+      }
+      attributes.add(attribute);
+    }
     if (attribute.getType() == Type.COMPLEX && includeAttributeChain) {
       List<Attribute> remaininAttributes = attribute.getAttributes();
       attributes.addAll(remaininAttributes);
diff --git a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/attribute/AttributeReference.java b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/attribute/AttributeReference.java
index bd7c592..fd90910 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/attribute/AttributeReference.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/attribute/AttributeReference.java
@@ -13,22 +13,20 @@
   @Urn
   String urn;
 
-  String parent;
-
   String attributeName;
 
+  String subAttributeName;
+
   public AttributeReference(String name) {
     int endOfUrn = name.lastIndexOf(':');
     String[] attributes = name.substring(endOfUrn + 1).split("\\.");
+    this.attributeName = attributes[0];
 
     if (endOfUrn > -1) {
       this.urn = name.substring(0, endOfUrn);
     }
     if (attributes.length > 1) {
-      this.parent = attributes[0];
-      this.attributeName = attributes[1];
-    } else if (attributes.length > 0) {
-      this.attributeName = attributes[0];
+      this.subAttributeName = attributes[1];
     }
   }
 
@@ -37,24 +35,22 @@
 
     if (name != null) {
       String[] attributes = name.split("\\.");
+      this.attributeName = attributes[0];
 
       if (attributes.length > 1) {
-        this.parent = attributes[0];
-        this.attributeName = attributes[1];
-      } else {
-        this.attributeName = attributes[0];
+        this.subAttributeName = attributes[1];
       }
     }
   }
 
-  public AttributeReference(String urn, String parent, String name) {
+  public AttributeReference(String urn, String attributeName, String subAttributeName) {
     this.urn = urn;
-    this.parent = parent;
-    this.attributeName = name;
+    this.attributeName = attributeName;
+    this.subAttributeName = subAttributeName;
   }
 
   public String getFullAttributeName() {
-    return (parent != null ? parent + "." : "") + this.attributeName;
+    return this.attributeName + (this.subAttributeName != null ? "." + this.subAttributeName : "");
   }
 
   public String getFullyQualifiedAttributeName() {
@@ -64,19 +60,16 @@
     if (this.urn != null) {
       sb.append(this.urn);
 
-      if (this.parent != null || this.attributeName != null) {
+      if (this.attributeName != null) {
         sb.append(":");
       }
     }
-    if (this.parent != null) {
-      sb.append(this.parent);
-
-      if (this.attributeName != null) {
-        sb.append(".");
-      }
-    }
     if (this.attributeName != null) {
-      sb.append(attributeName);
+      sb.append(this.attributeName);
+    }
+    if (this.subAttributeName != null) {
+      sb.append(".");
+      sb.append(subAttributeName);
     }
     fullyQualifiedAttributeName = sb.toString();
 
@@ -90,12 +83,12 @@
     if (this.urn != null) {
       sb.append(this.urn);
 
-      if (this.parent != null) {
+      if (this.subAttributeName != null) {
         sb.append(":");
+        sb.append(this.attributeName);
       }
-    }
-    if (this.parent != null) {
-      sb.append(this.parent);
+    } else if (this.subAttributeName != null) {
+      sb.append(this.attributeName);
     }
     attributeBase = sb.toString();
 
diff --git a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/data/PatchPathListener.java b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/data/PatchPathListener.java
index 5b4cbf0..d515d20 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/data/PatchPathListener.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/data/PatchPathListener.java
@@ -27,8 +27,8 @@
     attributeExpression.setAttributePath(urn, parentAttributeName);
 
     if (subAttributeName != null) {
-      attributePath.setParent(parentAttributeName);
-      attributePath.setAttributeName(subAttributeName);
+      attributePath.setAttributeName(parentAttributeName);
+      attributePath.setSubAttributeName(subAttributeName);
     }
     this.valuePathExpression = new ValuePathExpression(attributePath, attributeExpression);
   }
diff --git a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributeComparisonExpression.java b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributeComparisonExpression.java
index 5544616..ff4002a 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributeComparisonExpression.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributeComparisonExpression.java
@@ -31,6 +31,8 @@
   @Override
   public String toUnqualifiedFilter() {
     String compareValueString;
+    String subAttributeName = this.attributePath.getSubAttributeName();
+    String attributeName = subAttributeName != null ? subAttributeName : this.attributePath.getAttributeName();
 
     if (compareValue instanceof String) {
       compareValueString = QUOTE + compareValue + QUOTE;
@@ -45,7 +47,7 @@
     } else {
       compareValueString = "null";
     }
-    return attributePath.getAttributeName() + " " + operation + " " + compareValueString;
+    return attributeName + " " + operation + " " + compareValueString;
   }
 
   public static String toDateString(Date date) {
@@ -69,6 +71,8 @@
   @Override
   public void setAttributePath(String urn, String parentAttributeName) {
     this.attributePath.setUrn(urn);
-    this.attributePath.setParent(parentAttributeName);
+    String subAttributeName = this.attributePath.getAttributeName();
+    this.attributePath.setAttributeName(parentAttributeName);
+    this.attributePath.setSubAttributeName(subAttributeName);
   }
 }
diff --git a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributePresentExpression.java b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributePresentExpression.java
index 1b4a49e..d29f800 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributePresentExpression.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/AttributePresentExpression.java
@@ -14,12 +14,17 @@
 
   @Override
   public String toUnqualifiedFilter() {
-    return attributePath.getAttributeName() + " PR";
+    String subAttributeName = this.attributePath.getSubAttributeName();
+    String attributeName = subAttributeName != null ? subAttributeName : this.attributePath.getAttributeName();
+
+    return attributeName + " PR";
   }
 
   @Override
   public void setAttributePath(String urn, String parentAttributeName) {
     this.attributePath.setUrn(urn);
-    this.attributePath.setParent(parentAttributeName);
+    String subAttributeName = this.attributePath.getAttributeName();
+    this.attributePath.setAttributeName(parentAttributeName);
+    this.attributePath.setSubAttributeName(subAttributeName);
   }
 }
diff --git a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/ValuePathExpression.java b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/ValuePathExpression.java
index 0ab35c2..15fd64e 100644
--- a/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/ValuePathExpression.java
+++ b/scim-spec/scim-spec-protocol/src/main/java/edu/psu/swe/scim/spec/protocol/filter/ValuePathExpression.java
@@ -35,13 +35,12 @@
     String filter;
 
     if (this.attributeExpression != null) {
-      String parentAttribute = this.attributePath.getParent();
+      String subAttributeName = this.attributePath.getSubAttributeName();
       String attributeExpressionFilter = this.attributeExpression.toUnqualifiedFilter();
 
-      if (parentAttribute != null) {
+      if (subAttributeName != null) {
         String base = this.attributePath.getAttributeBase();
-        String subAttribute = this.attributePath.getAttributeName();
-        filter = base + "[" + attributeExpressionFilter + "]." + subAttribute;
+        filter = base + "[" + attributeExpressionFilter + "]." + subAttributeName;
       } else {
         String attribute = this.attributePath.getFullyQualifiedAttributeName();
         filter = attribute + "[" + attributeExpressionFilter + "]";
@@ -55,7 +54,9 @@
   @Override
   public void setAttributePath(String urn, String parentAttributeName) {
     this.attributePath.setUrn(urn);
-    this.attributePath.setParent(parentAttributeName);
+    String subAttributeName = this.attributePath.getAttributeName();
+    this.attributePath.setAttributeName(parentAttributeName);
+    this.attributePath.setSubAttributeName(subAttributeName);
     this.attributeExpression.setAttributePath(urn, parentAttributeName);
   }
 
@@ -64,19 +65,18 @@
     String filter;
 
     if (this.attributeExpression != null) {
-      String parentAttribute = this.attributePath.getParent();
+      String attributeName = this.attributePath.getAttributeName();
+      String subAttributeName = this.attributePath.getSubAttributeName();
       String attributeExpressionFilter = this.attributeExpression.toUnqualifiedFilter();
 
-      if (parentAttribute != null) {
-        String subAttribute = this.attributePath.getAttributeName();
-        filter = parentAttribute + "[" + attributeExpressionFilter + "]." + subAttribute;
+      if (subAttributeName != null) {
+        filter = attributeName + "[" + attributeExpressionFilter + "]." + subAttributeName;
       } else {
-        String attribute = this.attributePath.getAttributeName();
-        filter = attribute + "[" + attributeExpressionFilter + "]";
+        filter = attributeName + "[" + attributeExpressionFilter + "]";
       }
     } else {
-      String parent = this.attributePath.getParent();
-      filter = (parent != null ? parent + "." : "") + this.attributePath.getAttributeName();
+      String subAttributeName = this.attributePath.getSubAttributeName();
+      filter = this.attributePath.getAttributeName() + (subAttributeName != null ? "." + subAttributeName : "");
     }
     return filter;
   }