class ModifyAttributesOperationRecorder implements
        CompensatingTransactionOperationRecorder {

    public CompensatingTransactionOperationExecutor recordOperation(
            Object[] args) {
        Assert.notNull(args);
        Name dn = LdapTransactionUtils.getFirstArgumentAsName(args);
        if (args.length != 2 || !(args[1] instanceof ModificationItem[])) {
            throw new IllegalArgumentException(
                    "Unexpected arguments to ModifyAttributes operation");
        }

        ModificationItem[] incomingModifications = (ModificationItem[]) args[1];

        Set<String> set = new HashSet<String>();
        for (ModificationItem incomingModification : incomingModifications) {
            set.add(incomingModification.getAttribute().getID());
        }

        // Get the current values of all referred Attributes.
        String[] attributeNameArray = set.toArray(new String[set.size()]);

        // LDAP-234: We need to explicitly an IncrementalAttributesMapper in
        // case we're working against AD and there are too many attribute values to be returned
        // by one query.
        IncrementalAttributesMapper<?> attributesMapper = getAttributesMapper(attributeNameArray);
        while (attributesMapper.hasMore()) {
            ldapOperations.lookup(dn, attributesMapper.getAttributesForLookup(), attributesMapper);
        }

        Attributes currentAttributes = attributesMapper.getCollectedAttributes();

        // Get a compensating ModificationItem for each of the incoming
        // modification.
        ModificationItem[] rollbackItems = new ModificationItem[incomingModifications.length];
        for (int i = 0; i < incomingModifications.length; i++) {
            rollbackItems[i] = getCompensatingModificationItem(
                    currentAttributes, incomingModifications[i]);
        }

        return new ModifyAttributesOperationExecutor(ldapOperations, dn,
                incomingModifications, rollbackItems);
    }

    public  ModifyAttributesOperationRecorder(LdapOperations ldapOperations);

}