Set userGroups = groupCache.getGroups( userName.toNormName() );
Set userGroups = groupCache.getGroups( principalDn.toNormName() );
    public void add( NextInterceptor next, LdapDN normName, Attributes entry ) throws NamingException    {        // Access the principal requesting the operation, and bypass checks if it is the admin        Invocation invocation = InvocationStack.getInstance().peek();        LdapPrincipal principal = ( ( ServerContext ) invocation.getCaller() ).getPrincipal();        LdapDN userName = principal.getJndiName();        // bypass authz code if we are disabled        if ( !enabled )        {            next.add( normName, entry );            return;        }        // bypass authz code but manage caches if operation is performed by the admin        if ( userName.toNormName().equalsIgnoreCase( PartitionNexus.ADMIN_PRINCIPAL_NORMALIZED ) )        {            next.add( normName, entry );            tupleCache.subentryAdded( normName.toNormName(), normName, entry );            groupCache.groupAdded( normName.toNormName(), normName, entry );            return;        }        // perform checks below here for all non-admin users        SubentryService subentryService = ( SubentryService ) chain.get( "subentryService" );        Attributes subentryAttrs = subentryService.getSubentryAttributes( normName, entry );        NamingEnumeration attrList = entry.getAll();        while ( attrList.hasMore() )        {            subentryAttrs.put( ( Attribute ) attrList.next() );        }        // Assemble all the information required to make an access control decision        Set userGroups = groupCache.getGroups( userName.toNormName() );        Collection tuples = new HashSet();        // Build the total collection of tuples to be considered for add rights        // NOTE: entryACI are NOT considered in adds (it would be a security breech)        addPerscriptiveAciTuples( invocation.getProxy(), tuples, normName, subentryAttrs );        addSubentryAciTuples( invocation.getProxy(), tuples, normName, subentryAttrs );        // check if entry scope permission is granted        PartitionNexusProxy proxy = invocation.getProxy();        engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), normName, null, null,            ADD_PERMS, tuples, subentryAttrs );        // now we must check if attribute type and value scope permission is granted        NamingEnumeration attributeList = entry.getAll();        while ( attributeList.hasMore() )        {            Attribute attr = ( Attribute ) attributeList.next();            for ( int ii = 0; ii < attr.size(); ii++ )            {                engine.checkPermission( proxy, userGroups, userName, principal.getAuthenticationLevel(), normName, attr                    .getID(), attr.get( ii ), ADD_PERMS, tuples, entry );            }        }        // if we've gotten this far then access has been granted        next.add( normName, entry );        // if the entry added is a subentry or a groupOf[Unique]Names we must        // update the ACITuple cache and the groups cache to keep them in sync        tupleCache.subentryAdded( normName.toNormName(), normName, entry );        groupCache.groupAdded( normName.toNormName(), normName, entry );    }