text:
package org.wso2.carbon.registry.core.jdbc.handlers;

import org.apache.axiom.om.OMElement;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.registry.core.Association;
import org.wso2.carbon.registry.core.Collection;
import org.wso2.carbon.registry.core.Comment;
import org.wso2.carbon.registry.core.Resource;
import org.wso2.carbon.registry.core.Tag;
import org.wso2.carbon.registry.core.TaggedResourcePath;
import org.wso2.carbon.registry.core.config.RegistryContext;
import org.wso2.carbon.registry.core.exceptions.RegistryException;
import org.wso2.carbon.registry.core.jdbc.handlers.filters.Filter;
import org.wso2.carbon.registry.core.session.CurrentSession;
import org.wso2.carbon.utils.multitenancy.MultitenantConstants;

import java.util.Dictionary;
import java.util.Hashtable;

/**
 * This class is used to manage handlers belonging to a particular lifecycle phase. There are three
 * defined phases, default, reporting, and user.
 */
public class HandlerLifecycleManager extends HandlerManager {

    private Dictionary<String, HandlerManager> handlerManagers;

    /**
     * This phase contains the default system-level handlers.
     */
    public static final String DEFAULT_SYSTEM_HANDLER_PHASE = "default";

    /**
     * This phase contains the tenant-specific system-level handlers.
     */
    public static final String TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE = "tenant";

    /**
     * This phase contains the tenant-specific system-level handlers.
     */
    public static final String USER_DEFINED_SYSTEM_HANDLER_PHASE = "system";

    /**
     * This phase contains all the reporting handlers (such as WS-Eventing & Notification
     * handlers).
     */
    public static final String DEFAULT_REPORTING_HANDLER_PHASE = "reporting";

    /**
     * This phase contains user-defined handlers.
     */
    public static final String USER_DEFINED_HANDLER_PHASE = "user";

    /**
     * This phase contains the handlers that will get executed after a successful commit.
     */
    public static final String COMMIT_HANDLER_PHASE = "commit";

    /**
     * This phase contains the handlers that will get executed after the rollback of a failed
     * commit.
     */
    public static final String ROLLBACK_HANDLER_PHASE = "rollback";

    private static final Log log = LogFactory.getLog(HandlerLifecycleManager.class);

    /**
     * Creates a Handler Manager for a given handler lifecycle phase.
     */
    public HandlerLifecycleManager() {
        handlerManagers = new Hashtable<String, HandlerManager>();
        HandlerManager defaultHandlerManager = new HandlerManager();
        defaultHandlerManager.setEvaluateAllHandlers(false);
        handlerManagers.put(DEFAULT_SYSTEM_HANDLER_PHASE, defaultHandlerManager);
        HandlerManager defaultTenantSpecificHandlerManager = new UserDefinedHandlerManager();
        defaultTenantSpecificHandlerManager.setEvaluateAllHandlers(false);
        handlerManagers.put(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE,
                defaultTenantSpecificHandlerManager);
        HandlerManager userDefinedSystemHandlerManager = new HandlerManager();
        userDefinedSystemHandlerManager.setEvaluateAllHandlers(false);
        handlerManagers.put(USER_DEFINED_SYSTEM_HANDLER_PHASE, userDefinedSystemHandlerManager);
        HandlerManager userDefinedHandlerManager = new UserDefinedHandlerManager();
        userDefinedHandlerManager.setEvaluateAllHandlers(false);
        handlerManagers.put(USER_DEFINED_HANDLER_PHASE, userDefinedHandlerManager);
        HandlerManager reportingHandlerManager = new HandlerManager();
        reportingHandlerManager.setEvaluateAllHandlers(true);
        handlerManagers.put(DEFAULT_REPORTING_HANDLER_PHASE, reportingHandlerManager);

        HandlerManager commitHandlerManager = new UserDefinedHandlerManager();
        commitHandlerManager.setEvaluateAllHandlers(true);
        handlerManagers.put(COMMIT_HANDLER_PHASE, commitHandlerManager);
        HandlerManager rollbackHandlerManager = new UserDefinedHandlerManager();
        rollbackHandlerManager.setEvaluateAllHandlers(true);
        handlerManagers.put(ROLLBACK_HANDLER_PHASE, rollbackHandlerManager);

        init(MultitenantConstants.SUPER_TENANT_ID);
    }

    /**
     * An initialization method to be called in a multi-tenant environment.
     *
     * @param tenantId the identifier of the tenant.
     */
    public synchronized void init(int tenantId) {
        CurrentSession.setCallerTenantId(tenantId);
        try {
            UserDefinedHandlerManager userDefinedHandlerManager =
                    (UserDefinedHandlerManager) handlerManagers.get(
                            TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE);
            userDefinedHandlerManager.getUserHandlerManager();
            userDefinedHandlerManager =
                    (UserDefinedHandlerManager) handlerManagers.get(USER_DEFINED_HANDLER_PHASE);
            userDefinedHandlerManager.getUserHandlerManager();
        } finally {
            CurrentSession.removeCallerTenantId();
        }
    }

    /**
     * Method to obtain the handler manager for the specified phase.
     *
     * @param lifecyclePhase The name of the lifecycle phase.
     *
     * @return the handler manager corresponding to the specified phase.
     */
    public HandlerManager getHandlerManagerForPhase(String lifecyclePhase) {
        if (lifecyclePhase.equals(COMMIT_HANDLER_PHASE) ||
                lifecyclePhase.equals(ROLLBACK_HANDLER_PHASE)) {
            return handlerManagers.get(lifecyclePhase);
        } else {
            String msg = "Unable to provide handler manager for internally " +
                    "managed or invalid phase" + lifecyclePhase;
            log.error(msg);
            throw new SecurityException(msg);
        }
    }

    @Override
    public void addHandler(String[] methods, Filter filter, Handler handler) {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).addHandler(methods, filter, handler);
    }

    @Override
    public void addHandlerWithPriority(String[] methods, Filter filter, Handler handler) {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).addHandlerWithPriority(
                methods, filter, handler);
    }

    @Override
    public void removeHandler(Handler handler) {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).removeHandler(handler);
    }

    @Override
    public void removeHandler(String[] methods, Filter filter, Handler handler) {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).removeHandler(methods, filter, handler);
    }

    @Override
    public void addHandler(String[] methods, Filter filter, Handler handler,
                           String lifecyclePhase) {
        if (lifecyclePhase == null) {
            addHandler(methods, filter, handler);
            return;
        }
        HandlerManager hm = handlerManagers.get(lifecyclePhase);
        if (hm == null) {
            log.warn("Invalid handler lifecycle phase: " + lifecyclePhase +
                    ". Adding handler to the default phase.");
            addHandler(methods, filter, handler);
        } else {
            hm.addHandler(methods, filter, handler);
        }
    }

    @Override
    public void addHandlerWithPriority(String[] methods, Filter filter, Handler handler,
                                       String lifecyclePhase) {
        if (lifecyclePhase == null) {
            addHandlerWithPriority(methods, filter, handler);
            return;
        }
        HandlerManager hm = handlerManagers.get(lifecyclePhase);
        if (hm == null) {
            log.warn("Invalid handler lifecycle phase: " + lifecyclePhase +
                    ". Adding handler to the default phase.");
            addHandlerWithPriority(methods, filter, handler);
        } else {
            hm.addHandlerWithPriority(methods, filter, handler, lifecyclePhase);
        }
    }

    @Override
    public void removeHandler(Handler handler, String lifecyclePhase) {
        if (lifecyclePhase == null) {
            removeHandler(handler);
            return;
        }
        HandlerManager hm = handlerManagers.get(lifecyclePhase);
        if (hm == null) {
            log.warn("Invalid handler lifecycle phase: " + lifecyclePhase +
                    ". Removing handler from the default phase.");
            removeHandler(handler);
        } else {
            hm.removeHandler(handler, lifecyclePhase);
        }
    }

    @Override
    public void removeHandler(String[] methods, Filter filter, Handler handler,
                              String lifecyclePhase) {
        if (lifecyclePhase == null) {
            removeHandler(methods, filter, handler);
            return;
        }
        HandlerManager hm = handlerManagers.get(lifecyclePhase);
        if (hm == null) {
            log.warn("Invalid handler lifecycle phase: " + lifecyclePhase +
                    ". Removing handler from the default phase.");
            removeHandler(methods, filter, handler);
        } else {
            hm.removeHandler(methods, filter, handler, lifecyclePhase);
        }
    }

    @Override
    public void editComment(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).editComment(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).editComment(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).editComment(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).editComment(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).editComment(
						requestContext);
		}
    }

    @Override
    public void removeComment(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).removeComment(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).removeComment(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).removeComment(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).removeComment(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).removeComment(
						requestContext);
		}
    }

    @Override
    public void createVersion(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).createVersion(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).createVersion(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).createVersion(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).createVersion(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).createVersion(
						requestContext);
		}
    }

    @Override
    public void restoreVersion(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).restoreVersion(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).restoreVersion(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).restoreVersion(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).restoreVersion(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE)
						.restoreVersion(requestContext);
		}
    }

    @Override
    public void rateResource(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).rateResource(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).rateResource(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).rateResource(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).rateResource(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).rateResource(
						requestContext);
		}
    }

    @Override
    public void removeTag(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).removeTag(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).removeTag(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).removeTag(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).removeTag(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).removeTag(
					requestContext);
		}
    }

    @Override
    public void applyTag(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).applyTag(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).applyTag(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).applyTag(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).applyTag(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).applyTag(
					requestContext);
		}
    }

    @Override
    public void removeAssociation(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).removeAssociation(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).removeAssociation(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).removeAssociation(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).removeAssociation(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE)
					.removeAssociation(requestContext);
		}
    }

    @Override
    public void addAssociation(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).addAssociation(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).addAssociation(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).addAssociation(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).addAssociation(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE)
					.addAssociation(requestContext);
		}
    }

    @Override
    public void delete(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).delete(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).delete(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).delete(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).delete(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).delete(
					requestContext);
		}
    }

    @Override
    public void putChild(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).putChild(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).putChild(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).putChild(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).putChild(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).putChild(
					requestContext);
		}
    }

    @Override
    public void importChild(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).importChild(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).importChild(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).importChild(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).importChild(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).importChild(
					requestContext);
		}
    }

    @Override
    public void invokeAspect(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).invokeAspect(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).invokeAspect(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).invokeAspect(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).invokeAspect(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).invokeAspect(
					requestContext);
		}
    }

    @Override
    public void createLink(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).createLink(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).createLink(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).createLink(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).createLink(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).createLink(
					requestContext);
		}
    }

    @Override
    public void removeLink(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).removeLink(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).removeLink(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).removeLink(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).removeLink(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).removeLink(
					requestContext);
		}
    }

    @Override
    public void restore(RequestContext requestContext) throws RegistryException {
        handlerManagers.get(DEFAULT_SYSTEM_HANDLER_PHASE).restore(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            handlerManagers.get(TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).restore(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            handlerManagers.get(USER_DEFINED_SYSTEM_HANDLER_PHASE).restore(requestContext);
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        handlerManagers.get(USER_DEFINED_HANDLER_PHASE).restore(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).restore(
					requestContext);
		}
    }

    @Override
    public Association[] getAllAssociations(RequestContext requestContext)
            throws RegistryException {
        Association[] defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getAllAssociations(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Association[] tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getAllAssociations(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Association[] systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getAllAssociations(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Association[] userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getAllAssociations(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE)
					.getAllAssociations(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public Association[] getAssociations(RequestContext requestContext) throws RegistryException {
        Association[] defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getAssociations(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Association[] tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getAssociations(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Association[] systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getAssociations(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Association[] userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getAssociations(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE)
					.getAssociations(requestContext);
		}
        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public TaggedResourcePath[] getResourcePathsWithTag(RequestContext requestContext)
            throws RegistryException {
        TaggedResourcePath[] defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getResourcePathsWithTag(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            TaggedResourcePath[] tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getResourcePathsWithTag(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            TaggedResourcePath[] systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getResourcePathsWithTag(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        TaggedResourcePath[] userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getResourcePathsWithTag(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).getResourcePathsWithTag(
					requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public Tag[] getTags(RequestContext requestContext)
            throws RegistryException {
        Tag[] defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getTags(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Tag[] tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getTags(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Tag[] systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getTags(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Tag[] userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getTags(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).getTags(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public Comment[] getComments(RequestContext requestContext) throws RegistryException {
        Comment[] defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getComments(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Comment[] tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getComments(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Comment[] systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getComments(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Comment[] userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getComments(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE)
							.getComments(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public String[] getVersions(RequestContext requestContext) throws RegistryException {
        String[] defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getVersions(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String[] tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getVersions(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String[] systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getVersions(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String[] userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getVersions(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE)
					.getVersions(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public Collection executeQuery(RequestContext requestContext) throws RegistryException {
        Collection defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).executeQuery(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Collection tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).executeQuery(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Collection systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).executeQuery(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Collection userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).executeQuery(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).executeQuery(
					requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public Collection searchContent(RequestContext requestContext) throws RegistryException {
        Collection defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).searchContent(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Collection tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).searchContent(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Collection systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).searchContent(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Collection userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).searchContent(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).searchContent(
					requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public String addComment(RequestContext requestContext) throws RegistryException {
        String defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).addComment(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).addComment(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).addComment(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).addComment(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).addComment(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public Resource get(RequestContext requestContext) throws RegistryException {
        Resource defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).get(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            Resource tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).get(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            Resource systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).get(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        Resource userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).get(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);
        Resource resourceOnContext = requestContext.getResource();
        Resource output = (userDefinedValue != null) ? userDefinedValue : defaultValue;
        requestContext.setResource(output);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).get(requestContext);
		}
        requestContext.setResource(resourceOnContext);
        return output;
    }

    @Override
    public String put(RequestContext requestContext) throws RegistryException {
        String defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).put(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).put(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).put(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).put(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).put(requestContext);
		}
        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public String importResource(RequestContext requestContext) throws RegistryException {
        String defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).importResource(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).importResource(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).importResource(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).importResource(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		// Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(
					DEFAULT_REPORTING_HANDLER_PHASE).importResource(
					requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public String copy(RequestContext requestContext) throws RegistryException {
        String defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).copy(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).copy(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).copy(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).copy(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).copy(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public String move(RequestContext requestContext) throws RegistryException {
        String defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).move(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).move(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).move(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).move(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).move(
					requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public String rename(RequestContext requestContext) throws RegistryException {
        String defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).rename(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            String tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).rename(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            String systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).rename(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        String userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).rename(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).rename(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public OMElement dump(RequestContext requestContext) throws RegistryException {
        OMElement defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).dump(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            OMElement tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).dump(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            OMElement systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).dump(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        OMElement userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).dump(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).dump(
					requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public float getAverageRating(RequestContext requestContext) throws RegistryException {
        float defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getAverageRating(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            float tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getAverageRating(requestContext);
            if (tenantSpecificValue != -1) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            float systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getAverageRating(requestContext);
            if (systemSpecificValue != -1) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        float userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getAverageRating(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).getAverageRating(
					requestContext);
		}

        if (userDefinedValue != -1) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public int getRating(RequestContext requestContext) throws RegistryException {
        int defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getRating(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            int tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getRating(requestContext);
            if (tenantSpecificValue != -1) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            int systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getRating(requestContext);
            if (systemSpecificValue != -1) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        int userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getRating(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).getRating(requestContext);
		}

        if (userDefinedValue != -1) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public boolean resourceExists(RequestContext requestContext) throws RegistryException {
        boolean defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).resourceExists(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            boolean tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).resourceExists(requestContext);
            defaultValue = defaultValue || tenantSpecificValue;
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            boolean systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).resourceExists(requestContext);
            defaultValue = defaultValue || systemSpecificValue;
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        boolean userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).resourceExists(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).resourceExists(
					requestContext);
		}
		return userDefinedValue || defaultValue;
    }

    @Override
    public RegistryContext getRegistryContext(RequestContext requestContext) {
        RegistryContext defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).getRegistryContext(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            RegistryContext tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).getRegistryContext(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            RegistryContext systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).getRegistryContext(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        RegistryContext userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).getRegistryContext(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).getRegistryContext(requestContext);
		}
        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }

    @Override
    public OMElement dumpLite(RequestContext requestContext) throws RegistryException {
        OMElement defaultValue = handlerManagers.get(
                DEFAULT_SYSTEM_HANDLER_PHASE).dumpLite(requestContext);
        boolean isProcessingComplete = requestContext.isProcessingComplete();
        if (!isProcessingComplete) {
            OMElement tenantSpecificValue = handlerManagers.get(
                    TENANT_SPECIFIC_SYSTEM_HANDLER_PHASE).dumpLite(requestContext);
            if (tenantSpecificValue != null) {
                defaultValue = tenantSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        if (!isProcessingComplete) {
            OMElement systemSpecificValue = handlerManagers.get(
                    USER_DEFINED_SYSTEM_HANDLER_PHASE).dumpLite(requestContext);
            if (systemSpecificValue != null) {
                defaultValue = systemSpecificValue;
            }
            isProcessingComplete = requestContext.isProcessingComplete();
        }
        requestContext.setProcessingComplete(false);
        OMElement userDefinedValue = handlerManagers.get(
                USER_DEFINED_HANDLER_PHASE).dumpLite(requestContext);
        isProcessingComplete |= requestContext.isProcessingComplete();
        // The reporting handler phase needs to know about the state of processing
        requestContext.setProcessingComplete(isProcessingComplete);

		//Check process completion to avoid receiving two notifications
		if (!isProcessingComplete) {
			handlerManagers.get(DEFAULT_REPORTING_HANDLER_PHASE).dumpLite(requestContext);
		}

        if (userDefinedValue != null) {
            return userDefinedValue;
        }
        return defaultValue;
    }
}


text:
using namespace lingo;

// Bring specific functions in as overloads
// to support argument dependent lookup.
using lingo::is;
using lingo::as;
using lingo::cast;

struct Expr;
struct Literal_expr;
struct Id_expr;
struct Decl_expr;
struct Port_expr;
struct Overload_expr;
struct Add_expr;
struct Sub_expr;
struct Mul_expr;
struct Div_expr;
struct Rem_expr;
struct Lshift_expr;
struct Rshift_expr;
struct Bitwise_and_expr;
struct Bitwise_or_expr;
struct Xor_expr;
struct Neg_expr;
struct Pos_expr;
struct Eq_expr;
struct Ne_expr;
struct Lt_expr;
struct Gt_expr;
struct Le_expr;
struct Ge_expr;
struct And_expr;
struct Or_expr;
struct Not_expr;
struct Call_expr;
struct Dot_expr;
struct Field_expr;
struct Method_expr;
struct Index_expr;
struct Reinterpret_cast;
struct Void_cast;
struct Conv;
struct Value_conv;
struct Block_conv;
struct Promotion_conv;
struct Demotion_conv;
struct Sign_conv;
struct Integer_conv;
struct Variadic_conv;
struct Init;
struct Default_init;
struct Copy_init;
struct Reference_init;
struct Field_name_expr;
struct Field_access_expr;
struct Inport_expr;
struct Inphysport_expr;
struct All_port;
struct Controller_port;
struct Reflow_port;
struct Flood_port;
struct Egress_port;

struct Type;
struct Id_type;
struct Boolean_type;
struct Character_type;
struct Integer_type;
struct Function_type;
struct Array_type;
struct Block_type;
struct Reference_type;
struct Record_type;
struct Reference_type;
struct Layout_type;
struct Table_type;
struct Flow_type;
struct Port_type;
struct Void_type;
struct Context_type;
struct Key_type;
struct Opaque_type;
struct Varargs_type;

struct Decl;
struct Record_decl;
struct Member_decl;
struct Variable_decl;
struct Function_decl;
struct Parameter_decl;
struct Record_decl;
struct Field_decl;
struct Method_decl;
struct Module_decl;
struct Layout_decl;
struct Decode_decl;
struct Table_decl;
struct Key_decl;
struct Inport_key_decl;
struct Inphysport_key_decl;
struct Flow_decl;
struct Extracts_decl;
struct Rebind_decl;
struct Port_decl;
struct Event_decl;

struct Stmt;
struct Empty_stmt;
struct Block_stmt;
struct Assign_stmt;
struct Return_stmt;
struct Return_void_stmt;
struct If_then_stmt;
struct If_else_stmt;
struct Match_stmt;
struct Case_stmt;
struct While_stmt;
struct Break_stmt;
struct Continue_stmt;
struct Expression_stmt;
struct Declaration_stmt;

// Network specific
struct Decode_stmt;
struct Goto_stmt;

// Builtins
struct Bind_offset;
struct Bind_header;
struct Alias_bind;
struct Load_field;
struct Create_table;
struct Delete_table;
struct Lookup;
struct Advance;

// Actions
struct Action;
struct Drop;
struct Output;
struct Output_egress;
struct Clear;
struct Group;
struct Set_field;
struct Copy_field;
struct Insert_flow;
struct Remove_flow;
struct Remove_miss;
struct Raise;
struct Write_output;
struct Write_set_field;
struct Write_copy_field;

using Expr_seq = std::vector<Expr*>;
using Type_seq = std::vector<Type const*>;
using Decl_seq = std::vector<Decl*>;
using Stmt_seq = std::vector<Stmt*>;

using uint128_t = boost::multiprecision::checked_uint128_t;
using uint512_t = boost::multiprecision::checked_uint512_t;

#include <beaker/symbol.hpp> // TODO: Do I need this?
#include <beaker/print.hpp>

#endif

redpajama_set_name: RedPajamaGithub


text:
For today's hackday I am going to try and start to build an access controlled "route" in solid-server, which grants access to a resource based on a credit system.  If you have credits, it will show you the resource.  If not you will get a 402.  This builds a bit more functionality on the code written for the previous [hack day](http://melvincarvalho.github.io/markdown-editor/?uri=https://melvin.databox.me/.markdown/hackday/route.txt).  I'll try and incorporate the work from the web payments WG [http://w3c.github.io/webpayments-http-api/](http://w3c.github.io/webpayments-http-api/).

## Components

The demo contains 4 components

* /pay -- the resource that costs 25 credits to view
* /balance -- shows your balance
* /faucet -- a small app that will see your balance
* /home -- navigation and instructions

Each was deployed as a custom route with its own handler.

## Installation

Installation is via

    git clone https://github.com/melvincarvalho/402.git

Then run

    npm install

```bash
$ bin/server.js  --port 8443 --ssl-key path/to/ssl-key.pem --ssl-cert path/to/ssl-cert.pem
# server running on https://localhost:8443/
```

##### How do I get the --ssl-key and the --ssl-cert?
You need an SSL certificate you get this from your domain provider or for free from [Let's Encrypt!](https://letsencrypt.org/getting-started/).

If you don't have one yet, or you just want to test `solid`, generate a certificate
```
$ openssl genrsa 2048 > ../localhost.key
$ openssl req -new -x509 -nodes -sha256 -days 3650 -key ../localhost.key -subj '/CN=*.localhost' > ../localhost.cert
```

## Faucet

Using [webcredits](https://webcredits.org/) it is possible to set up a faucet using

    credit create

    credit genesis

    credit insert https://w3id.org/cc#coinbase 50000 '' https://w3id.org/cc#faucet

## Demo

[Demo](https://webcredits.org:3000/)


text:
class Content < ActiveRecord::Base
  module ContentAnnotable
    ##
    # @param user [User]
    # @return [ContentNote] notes by provided
    #   user (if any)
    def user_note(user)
      content_notes.find_by(
        user: user
      )
    end
  end
end


text:
package 'libgmp-dev'

include_recipe 'rvm::system'
include_recipe 'rvm::gem_package'


text:
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using XenAPI;
using XenAdmin.Actions;
using XenAdmin.Core;
using XenAdmin.Dialogs;
using XenAdmin.Network;
using XenAdmin.Wizards;

namespace XenAdmin.Commands
{
    /// <summary>
    /// IF HA is not enabled, it launches the HA wizard, otherwise the HA config dialog
    /// </summary>
    internal class HAConfigureCommand : HACommand
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

        private RbacMethodList HA_PERMISSION_CHECKS = new RbacMethodList(
            "pool.set_ha_host_failures_to_tolerate",
            "pool.sync_database",
            "vm.set_ha_restart_priority",
            "pool.ha_compute_hypothetical_max_host_failures_to_tolerate"
        );

        /// <summary>
        /// Initializes a new instance of this Command. The parameter-less constructor is required if
        /// this Command is to be attached to a ToolStrip menu item or button. It should not be used in any other scenario.
        /// </summary>
        public HAConfigureCommand()
        {
        }

        public HAConfigureCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
            : base(mainWindow, selection)
        {
        }

        public HAConfigureCommand(IMainWindow mainWindow, IXenConnection connection)
            : base(mainWindow, Helpers.GetPoolOfOne(connection))
        {
        }

        public HAConfigureCommand(IMainWindow mainWindow, Pool pool)
            : base(mainWindow, pool)
        {
        }

        private void Run(IXenConnection connection)
        {
            if (connection == null)
                return;

            Pool pool = Helpers.GetPool(connection);
            if (pool == null)
                return;

            if (Helpers.FeatureForbidden(pool, Host.RestrictHA))
            {
                UpsellDialog.ShowUpsellDialog(Messages.UPSELL_BLURB_HA, Parent);
            }
            else if (pool.ha_enabled)
            {
                if (pool.ha_statefiles.All(sf => pool.Connection.Resolve(new XenRef<VDI>(sf)) == null))//empty gives true, which is correct
                {
                    log.ErrorFormat("Cannot resolve HA statefile VDI (pool {0} has {1} statefiles).",
                        pool.Name(), pool.ha_statefiles.Length);

                    using (var dlg = new ErrorDialog(string.Format(Messages.HA_CONFIGURE_NO_STATEFILE, Helpers.GetName(pool).Ellipsise(30)),
                        ThreeButtonDialog.ButtonOK)
                    {
                        WindowTitle = Messages.CONFIGURE_HA
                    })
                    {
                        dlg.ShowDialog(Program.MainWindow);
                    }
                }
                else if (!Role.CanPerform(HA_PERMISSION_CHECKS, pool.Connection, out _))
                {
                    var msg = string.Format(Messages.RBAC_HA_CONFIGURE_WARNING,
                        Role.FriendlyCSVRoleList(Role.ValidRoleList(HA_PERMISSION_CHECKS, pool.Connection)),
                        Role.FriendlyCSVRoleList(pool.Connection.Session.Roles));

                    using (var dlg = new ErrorDialog(msg))
                        dlg.ShowDialog(Parent);
                }
                else
                {
                    MainWindowCommandInterface.ShowPerConnectionWizard(connection, new EditVmHaPrioritiesDialog(pool));
                }
            }
            else
            {
                MainWindowCommandInterface.ShowPerConnectionWizard(connection, new HAWizard(pool));
            }
        }

        protected override void RunCore(SelectedItemCollection selection)
        {
            Run(selection[0].Connection);
        }

        protected override bool CanRunCore(SelectedItemCollection selection)
        {
            return CanRunHACommand(selection);
        }

        protected override string GetCantRunReasonCore(IXenObject item)
        {
            var reason = base.GetCantRunReasonCore(item);
            if (!string.IsNullOrEmpty(reason) && reason != Messages.UNKNOWN)
                return reason;

            Pool pool = item == null ? null : Helpers.GetPool(item.Connection);

            if (pool != null && !pool.Connection.Cache.Hosts.Any(Host.RestrictPoolSecretRotation) && pool.is_psr_pending)
                return Messages.ROTATE_POOL_SECRET_PENDING_HA;

            return Messages.UNKNOWN;
        }

        protected override bool CanRun(Pool pool)
        {
            return pool.Connection.Cache.Hosts.Any(Host.RestrictPoolSecretRotation) || !pool.is_psr_pending;
        }

        public override string MenuText => Messages.CONFIGURE_HA_ELLIPSIS;
    }

    internal class HADisableCommand : HACommand
    {
        /// <summary>
        /// Initializes a new instance of this Command. The parameter-less constructor is required if
        /// this Command is to be attached to a ToolStrip menu item or button. It should not be used in any other scenario.
        /// </summary>
        public HADisableCommand()
        {
        }

        public HADisableCommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
            : base(mainWindow, selection)
        {
        }

        public HADisableCommand(IMainWindow mainWindow, IXenConnection connection)
            : base(mainWindow, Helpers.GetPoolOfOne(connection))
        {
        }

        protected override void RunCore(SelectedItemCollection selection)
        {
            Pool pool = selection.Count == 1 ? selection[0].PoolAncestor : null;
            if (pool == null || !pool.ha_enabled)
                return;

            if (pool.ha_statefiles.All(sf => pool.Connection.Resolve(new XenRef<VDI>(sf)) == null)) //empty gives true, which is correct
            {
                using (var dlg = new ErrorDialog(string.Format(Messages.HA_DISABLE_NO_STATEFILE,
                        Helpers.GetName(pool).Ellipsise(30)),
                    ThreeButtonDialog.ButtonOK)
                {
                    WindowTitle = Messages.DISABLE_HA
                })
                {
                    dlg.ShowDialog(Parent);
                    return;
                }
            }

            // Confirm the user wants to disable HA
            using (var dlg = new NoIconDialog(string.Format(Messages.HA_DISABLE_QUERY,
                    Helpers.GetName(pool).Ellipsise(30)),
                ThreeButtonDialog.ButtonYes, ThreeButtonDialog.ButtonNo)
            {
                HelpNameSetter = "HADisable",
                WindowTitle = Messages.DISABLE_HA
            })
            {
                if (dlg.ShowDialog(Parent) != DialogResult.Yes)
                    return;
            }

            var action = new DisableHAAction(pool);
            // We will need to re-enable buttons when the action completes
            action.Completed += Program.MainWindow.action_Completed;
            action.RunAsync();
        }

        protected override bool CanRunCore(SelectedItemCollection selection)
        {
            return CanRunHACommand(selection);
        }

        protected override bool CanRun(Pool pool)
        {
            return pool.ha_enabled;
        }

        public override string MenuText => Messages.DISABLE_HA_HOTKEY;
    }

    internal class HACommand : Command
    {
        public HACommand()
        {
        }

        public HACommand(IMainWindow mainWindow, IEnumerable<SelectedItem> selection)
            : base(mainWindow, selection)
        {
        }

        public HACommand(IMainWindow mainWindow, IXenConnection connection)
            : base(mainWindow, Helpers.GetPoolOfOne(connection))
        {
        }

        public HACommand(IMainWindow mainWindow, Pool pool)
            : base(mainWindow, pool)
        {
        }

        protected override bool CanRunCore(SelectedItemCollection selection)
        {
            return new HAConfigureCommand(MainWindowCommandInterface, selection).CanRun() ||
                   new HADisableCommand(MainWindowCommandInterface, selection).CanRun();
        }

        protected override string GetCantRunReasonCore(IXenObject item)
        {
            Pool pool = item == null ? null : Helpers.GetPoolOfOne(item.Connection);

            if (pool == null)
                return string.Format(Messages.POOL_GONE, BrandManager.BrandConsole);

            if (!pool.IsVisible())
                return Messages.HA_STANDALONE_SERVER;

            Host coordinator = Helpers.GetCoordinator(pool.Connection);
            if (coordinator == null)
                return string.Format(Messages.POOL_COORDINATOR_GONE, BrandManager.BrandConsole);

            if (pool.Locked)
                return Messages.POOL_EDIT_IN_PROGRESS;

            var action = HelpersGUI.FindActiveHaAction(pool.Connection);
            if (action != null)
                return string.Format(action is EnableHAAction ? Messages.HA_PAGE_ENABLING : Messages.HA_PAGE_DISABLING,
                    Helpers.GetName(pool.Connection));

            return Messages.UNKNOWN;
        }

        protected bool CanRunHACommand(SelectedItemCollection selection)
        {
            if (selection.Count != 1)
                return false;

            Pool pool = selection[0].PoolAncestor;

            if (pool == null || pool.Locked ||
                pool.Connection == null || !pool.Connection.IsConnected ||
                Helpers.GetCoordinator(pool.Connection) == null ||
                HelpersGUI.FindActiveHaAction(pool.Connection) != null)
                return false;

            return CanRun(pool);
        }

        protected virtual bool CanRun(Pool pool)
        {
            return true;
        }

        public override string MenuText => Messages.MAINWINDOW_HIGH_AVAILABILITY;
    }
}


text:
package com.esotericsoftware.kryonet;

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.minlog.Log;

import java.io.IOException;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

public class UnregisteredClassTest extends KryoNetTestCase {
	public void testUnregisteredClasses () throws IOException {
		final Data dataTCP = new Data();
		populateData(dataTCP, true);
		final Data dataUDP = new Data();
		populateData(dataUDP, false);

		final AtomicInteger receivedTCP = new AtomicInteger();
		final AtomicInteger receivedUDP = new AtomicInteger();

		final Server server = new Server(1024 * 32, 1024 * 16);
		server.getKryo().setRegistrationRequired(false);
		startEndPoint(server);
		server.bind(tcpPort, udpPort);
		server.addListener(new Listener() {
			public void connected (Connection connection) {
				connection.sendTCP(dataTCP);
				connection.sendUDP(dataUDP);
			}

			public void received (Connection connection, Object object) {
				if (object instanceof Data) {
					Data data = (Data)object;
					if (data.isTCP) {
						if (!data.equals(dataTCP)) fail();
						receivedTCP.incrementAndGet();
					} else {
						if (!data.equals(dataUDP)) fail();
						receivedUDP.incrementAndGet();
					}
				}
			}
		});

		// ----

		final Client client = new Client(1024 * 32, 1024 * 16);
		client.getKryo().setRegistrationRequired(false);
		startEndPoint(client);
		client.addListener(new Listener() {
			public void received (Connection connection, Object object) {
				if (object instanceof Data) {
					Data data = (Data)object;
					if (data.isTCP) {
						if (!data.equals(dataTCP)) fail();
						receivedTCP.incrementAndGet();
						connection.sendTCP(data);
					} else {
						if (!data.equals(dataUDP)) fail();
						receivedUDP.incrementAndGet();
						connection.sendUDP(data);
					}
				}
			}
		});

		client.connect(5000, host, tcpPort, udpPort);

		waitForThreads(5000);

		assertEquals(2, receivedTCP.intValue());
		assertEquals(2, receivedUDP.intValue());
	}

	private void populateData (Data data, boolean isTCP) {
		data.isTCP = isTCP;

		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < 3000; i++)
			buffer.append('a');
		data.string = buffer.toString();

		data.strings = new String[] {"abcdefghijklmnopqrstuvwxyz0123456789", "", null, "!@#$", "�����"};
		data.ints = new int[] {-1234567, 1234567, -1, 0, 1, Integer.MAX_VALUE, Integer.MIN_VALUE};
		data.shorts = new short[] {-12345, 12345, -1, 0, 1, Short.MAX_VALUE, Short.MIN_VALUE};
		data.floats = new float[] {0, -0, 1, -1, 123456, -123456, 0.1f, 0.2f, -0.3f, (float)Math.PI, Float.MAX_VALUE,
			Float.MIN_VALUE};
		data.doubles = new double[] {0, -0, 1, -1, 123456, -123456, 0.1d, 0.2d, -0.3d, Math.PI, Double.MAX_VALUE, Double.MIN_VALUE};
		data.longs = new long[] {0, -0, 1, -1, 123456, -123456, 99999999999l, -99999999999l, Long.MAX_VALUE, Long.MIN_VALUE};
		data.bytes = new byte[] {-123, 123, -1, 0, 1, Byte.MAX_VALUE, Byte.MIN_VALUE};
		data.chars = new char[] {32345, 12345, 0, 1, 63, Character.MAX_VALUE, Character.MIN_VALUE};
		data.booleans = new boolean[] {true, false};
		data.Ints = new Integer[] {-1234567, 1234567, -1, 0, 1, Integer.MAX_VALUE, Integer.MIN_VALUE};
		data.Shorts = new Short[] {-12345, 12345, -1, 0, 1, Short.MAX_VALUE, Short.MIN_VALUE};
		data.Floats = new Float[] {0f, -0f, 1f, -1f, 123456f, -123456f, 0.1f, 0.2f, -0.3f, (float)Math.PI, Float.MAX_VALUE,
			Float.MIN_VALUE};
		data.Doubles = new Double[] {0d, -0d, 1d, -1d, 123456d, -123456d, 0.1d, 0.2d, -0.3d, Math.PI, Double.MAX_VALUE,
			Double.MIN_VALUE};
		data.Longs = new Long[] {0l, -0l, 1l, -1l, 123456l, -123456l, 99999999999l, -99999999999l, Long.MAX_VALUE, Long.MIN_VALUE};
		data.Bytes = new Byte[] {-123, 123, -1, 0, 1, Byte.MAX_VALUE, Byte.MIN_VALUE};
		data.Chars = new Character[] {32345, 12345, 0, 1, 63, Character.MAX_VALUE, Character.MIN_VALUE};
		data.Booleans = new Boolean[] {true, false};
	}

	static public class Data {
		public String string;
		public String[] strings;
		public int[] ints;
		public short[] shorts;
		public float[] floats;
		public double[] doubles;
		public long[] longs;
		public byte[] bytes;
		public char[] chars;
		public boolean[] booleans;
		public Integer[] Ints;
		public Short[] Shorts;
		public Float[] Floats;
		public Double[] Doubles;
		public Long[] Longs;
		public Byte[] Bytes;
		public Character[] Chars;
		public Boolean[] Booleans;
		public boolean isTCP;

		public int hashCode () {
			final int prime = 31;
			int result = 1;
			result = prime * result + Arrays.hashCode(Booleans);
			result = prime * result + Arrays.hashCode(Bytes);
			result = prime * result + Arrays.hashCode(Chars);
			result = prime * result + Arrays.hashCode(Doubles);
			result = prime * result + Arrays.hashCode(Floats);
			result = prime * result + Arrays.hashCode(Ints);
			result = prime * result + Arrays.hashCode(Longs);
			result = prime * result + Arrays.hashCode(Shorts);
			result = prime * result + Arrays.hashCode(booleans);
			result = prime * result + Arrays.hashCode(bytes);
			result = prime * result + Arrays.hashCode(chars);
			result = prime * result + Arrays.hashCode(doubles);
			result = prime * result + Arrays.hashCode(floats);
			result = prime * result + Arrays.hashCode(ints);
			result = prime * result + (isTCP ? 1231 : 1237);
			result = prime * result + Arrays.hashCode(longs);
			result = prime * result + Arrays.hashCode(shorts);
			result = prime * result + ((string == null) ? 0 : string.hashCode());
			result = prime * result + Arrays.hashCode(strings);
			return result;
		}

		public boolean equals (Object obj) {
			if (this == obj) return true;
			if (obj == null) return false;
			if (getClass() != obj.getClass()) return false;
			Data other = (Data)obj;
			if (!Arrays.equals(Booleans, other.Booleans)) return false;
			if (!Arrays.equals(Bytes, other.Bytes)) return false;
			if (!Arrays.equals(Chars, other.Chars)) return false;
			if (!Arrays.equals(Doubles, other.Doubles)) return false;
			if (!Arrays.equals(Floats, other.Floats)) return false;
			if (!Arrays.equals(Ints, other.Ints)) return false;
			if (!Arrays.equals(Longs, other.Longs)) return false;
			if (!Arrays.equals(Shorts, other.Shorts)) return false;
			if (!Arrays.equals(booleans, other.booleans)) return false;
			if (!Arrays.equals(bytes, other.bytes)) return false;
			if (!Arrays.equals(chars, other.chars)) return false;
			if (!Arrays.equals(doubles, other.doubles)) return false;
			if (!Arrays.equals(floats, other.floats)) return false;
			if (!Arrays.equals(ints, other.ints)) return false;
			if (isTCP != other.isTCP) return false;
			if (!Arrays.equals(longs, other.longs)) return false;
			if (!Arrays.equals(shorts, other.shorts)) return false;
			if (string == null) {
				if (other.string != null) return false;
			} else if (!string.equals(other.string)) return false;
			if (!Arrays.equals(strings, other.strings)) return false;
			return true;
		}

		public String toString () {
			return "Data";
		}
	}
}


text:
/**
 * This class is used to send requests to the server using {@link Ext.direct.Manager Ext.Direct}. When a
 * request is made, the transport mechanism is handed off to the appropriate
 * {@link Ext.direct.RemotingProvider Provider} to complete the call.
 *
 * # Specifying the function
 *
 * This proxy expects a Direct remoting method to be passed in order to be able to complete requests.
 * This can be done by specifying the {@link #directFn} configuration. This will use the same direct
 * method for all requests. Alternatively, you can provide an {@link #api} configuration. This
 * allows you to specify a different remoting method for each CRUD action.
 *
 * # Parameters
 *
 * This proxy provides options to help configure which parameters will be sent to the server.
 * By specifying the {@link #paramsAsHash} option, it will send an object literal containing each
 * of the passed parameters. The {@link #paramOrder} option can be used to specify the order in which
 * the remoting method parameters are passed.
 *
 * # Example Usage
 *
 *     Ext.define('User', {
 *         extend: 'Ext.data.Model',
 *         fields: ['firstName', 'lastName'],
 *         proxy: {
 *             type: 'direct',
 *             directFn: MyApp.getUsers,
 *             paramOrder: 'id' // Tells the proxy to pass the id as the first parameter to the remoting method.
 *         }
 *     });
 *     User.load(1);
 */
Ext.define('Ext.data.proxy.Direct', {
    /* Begin Definitions */

    extend: 'Ext.data.proxy.Server',
    alternateClassName: 'Ext.data.DirectProxy',

    alias: 'proxy.direct',

    requires: ['Ext.direct.Manager'],

    /* End Definitions */

    /**
     * @cfg {String/String[]} paramOrder
     * Defaults to undefined. A list of params to be executed server side.  Specify the params in the order in
     * which they must be executed on the server-side as either (1) an Array of String values, or (2) a String
     * of params delimited by either whitespace, comma, or pipe. For example, any of the following would be
     * acceptable:
     *
     *     paramOrder: ['param1','param2','param3']
     *     paramOrder: 'param1 param2 param3'
     *     paramOrder: 'param1,param2,param3'
     *     paramOrder: 'param1|param2|param'
     */
    paramOrder: undefined,

    /**
     * @cfg {Boolean} paramsAsHash
     * Send parameters as a collection of named arguments.
     * Providing a {@link #paramOrder} nullifies this configuration.
     */
    paramsAsHash: true,

    /**
     * @cfg {Function/String} directFn
     * Function to call when executing a request. directFn is a simple alternative to defining the api configuration-parameter
     * for Store's which will not implement a full CRUD api. The directFn may also be a string reference to the fully qualified
     * name of the function, for example: 'MyApp.company.GetProfile'. This can be useful when using dynamic loading. The string
     * will be looked up when the proxy is created.
     */
    directFn : undefined,

    /**
     * @cfg {Object} api
     * The same as {@link Ext.data.proxy.Server#api}, however instead of providing urls, you should provide a direct
     * function call. See {@link #directFn}.
     */

    /**
     * @cfg {Object} extraParams
     * Extra parameters that will be included on every read request. Individual requests with params
     * of the same name will override these params when they are in conflict.
     */

    // private
    paramOrderRe: /[\s,|]/,

    constructor: function(config){
        var me = this,
            paramOrder;

        me.callParent(arguments);

        paramOrder = me.paramOrder;
        if (Ext.isString(paramOrder)) {
            me.paramOrder = paramOrder.split(me.paramOrderRe);
        }
    },

    resolveMethods: function() {
        var me = this,
            fn = me.directFn,
            api = me.api,
            Manager = Ext.direct.Manager,
            method;

        if (fn) {
            method = me.directFn = Manager.parseMethod(fn);

            if (!Ext.isFunction(method)) {
                Ext.Error.raise('Cannot resolve directFn ' + fn);
            }
        }
        else if (api) {
            for (fn in api) {
                if (api.hasOwnProperty(fn)) {
                    method = api[fn];
                    api[fn] = Manager.parseMethod(method);

                    if (!Ext.isFunction(api[fn])) {
                        Ext.Error.raise('Cannot resolve Direct api ' + fn + ' method ' + method);
                    }
                }
            }
        }

        me.methodsResolved = true;
    },

    doRequest: function(operation, callback, scope) {
        var me = this,
            writer = me.getWriter(),
            request = me.buildRequest(operation),
            params = request.params,
            args = [],
            fn, method;

        if (!me.methodsResolved) {
            me.resolveMethods();
        }

        fn = me.api[request.action] || me.directFn;

        //<debug>
        if (!fn) {
            Ext.Error.raise('No direct function specified for this proxy');
        }
        //</debug>

        if (operation.allowWrite()) {
            request = writer.write(request);
        }

        if (operation.action == 'read') {
            // We need to pass params
            method = fn.directCfg.method;
            args = method.getArgs(params, me.paramOrder, me.paramsAsHash);
        } else {
            args.push(request.jsonData);
        }

        Ext.apply(request, {
            args: args,
            directFn: fn
        });
        args.push(me.createRequestCallback(request, operation, callback, scope), me);
        fn.apply(window, args);
    },

    /*
     * Inherit docs. We don't apply any encoding here because
     * all of the direct requests go out as jsonData
     */
    applyEncoding: Ext.identityFn,

    createRequestCallback: function(request, operation, callback, scope){
        var me = this;

        return function(data, event){
            me.processResponse(event.status, operation, request, event, callback, scope);
        };
    },

    // inherit docs
    extractResponseData: function(response){
        return Ext.isDefined(response.result) ? response.result : response.data;
    },

    // inherit docs
    setException: function(operation, response) {
        operation.setException(response.message);
    },

    // inherit docs
    buildUrl: function(){
        return '';
    }
});


text:
class PrefService;

namespace base {
class Clock;
class Time;
}  // namespace base

namespace component_updater {
class ComponentUpdateService;
}  // namespace component_updater

namespace crostini {

// If Crostini usage reporting is enabled, store the time window of
// the last app launch and the Termina version in prefs.
void WriteMetricsForReportingToPrefsIfEnabled(
    PrefService* profile_prefs,
    const component_updater::ComponentUpdateService* update_service,
    const base::Clock* clock);

// Cache the Termina VM kernel in profile prefs from where they
// are copied to the device status proto during status collection
// in case advanced Crostini reporting is enabled.
void WriteTerminaVmKernelVersionToPrefsForReporting(
    PrefService* profile_prefs,
    const std::string& kernel_version);

// "Coarsens" the given time to the start of a three-day time window.
// Used for privacy reasons.
base::Time GetThreeDayWindowStart(const base::Time& actual_time);

// Retrieve the cros-termina version from the browser's component list.
std::string GetTerminaVersion(
    const component_updater::ComponentUpdateService* update_service);

}  // namespace crostini

#endif  // CHROME_BROWSER_ASH_CROSTINI_CROSTINI_REPORTING_UTIL_H_


text:
layout: page
description: "Full publication list for Hexiang"
noindex:  true
---

    Full Publication List

  {% for publication in site.data.publications %}

        {{ publication.title }}

        {% for author in publication.authors %}

          {{ author.name | prepend: ' '}}
          {% if author.equal_contribution %} * {% endif %}

        {% if forloop.last == false %},{% endif %}
        {% endfor %}

{{ publication.desc }}

        {{ publication.publisher }}
        {{ publication.status }}
        {{ publication.place }}

        {% for tag in publication.tags %}
        [  {{ tag.name }}  ]
        {% endfor %}

  {% endfor %}

       Back