private static KerberosIdentityDescriptor processIdentity(KerberosIdentityDescriptor previousStackIdentity,
                                                            KerberosIdentityDescriptor newStackIdentity,
                                                            KerberosIdentityDescriptor userIdentity) {

    KerberosIdentityDescriptor updatedValue = new KerberosIdentityDescriptor(newStackIdentity.toMap());
    KerberosPrincipalDescriptor updatedValuePrincipal = updatedValue.getPrincipalDescriptor();
    KerberosKeytabDescriptor updatedValueKeytab = updatedValue.getKeytabDescriptor();

    // If the new identity definition is a reference and no longer has a principal definition,
    // Ignore any user changes to the old principal definition.
    if (updatedValuePrincipal != null) {
      KerberosPrincipalDescriptor oldValuePrincipal = (previousStackIdentity == null) ? null : previousStackIdentity.getPrincipalDescriptor();
      String previousValuePrincipalValue = null;
      KerberosPrincipalDescriptor userValuePrincipal = userIdentity.getPrincipalDescriptor();
      String userValuePrincipalValue = null;

      if (oldValuePrincipal != null) {
        previousValuePrincipalValue = oldValuePrincipal.getValue();
      }

      if (userValuePrincipal != null) {
        userValuePrincipalValue = userValuePrincipal.getValue();
      }

      // If the user changed the stack default, replace the new stack default value with the user's
      // changed value
      if ((userValuePrincipalValue != null) && !userValuePrincipalValue.equals(previousValuePrincipalValue)) {
        updatedValuePrincipal.setValue(userValuePrincipalValue);
      }
    }

    // If the new identity definition is a reference and no longer has a keytab definition,
    // Ignore any user changes to the old keytab definition.
    if (updatedValueKeytab != null) {
      KerberosKeytabDescriptor oldValueKeytab = (previousStackIdentity == null) ? null : previousStackIdentity.getKeytabDescriptor();
      String previousValueKeytabFile = null;
      KerberosKeytabDescriptor userValueKeytab = userIdentity.getKeytabDescriptor();
      String userValueKeytabFile = null;

      if (oldValueKeytab != null) {
        previousValueKeytabFile = oldValueKeytab.getFile();
      }

      if (userValueKeytab != null) {
        userValueKeytabFile = userValueKeytab.getFile();
      }

      // If the user changed the stack default, replace the new stack default value with the user's
      // changed value
      if ((userValueKeytabFile != null) && !userValueKeytabFile.equals(previousValueKeytabFile)) {
        updatedValueKeytab.setFile(userValueKeytabFile);
      }
    }

    // Remove the when clause
    updatedValue.setWhen(null);

    return updatedValue;
  }
Processes a {@link KerberosIdentityDescriptor} to change the user-supplied data based on the changes
observed between the previous stack version's data and the new stack version's data.
<p>
It is expected that <code>newStackIdentities</code> and <code>userIdentities</code> are not null.
However, <code>previousStackIdentities</code> may be null in the event the user added a Kerberos
identity that was then added in the new Kerberos descriptor.  In this case, the user's values
for the principal name and keytab file are kept while adding any other changes from tne new stack.

@param previousStackIdentity a {@link KerberosIdentityDescriptor} from the previous stack version's Kerberos descriptor
@param newStackIdentity      a {@link KerberosIdentityDescriptor} from the new stack version's Kerberos descriptor
@param userIdentity          a {@link KerberosIdentityDescriptor} from the user-specified Kerberos descriptor
@return a new, updated, {@link KerberosIdentityDescriptor}
ambari-server/src/main/java/org/apache/ambari/server/state/kerberos/KerberosDescriptorUpdateHelper.java