class GridCollisionManager extends GridManagerAdapter<CollisionSpi> {
    /** Reference for external listener. */
    private final AtomicReference<CollisionExternalListener> extLsnr =
        new AtomicReference<>();

    /**
     * @param ctx Grid kernal context.
     */
    public GridCollisionManager(GridKernalContext ctx) {
        super(ctx, ctx.config().getCollisionSpi());
    }

    /** {@inheritDoc} */
    @Override public void start() throws IgniteCheckedException {
        startSpi();

        if (enabled()) {
            getSpi().setExternalCollisionListener(new CollisionExternalListener() {
                @Override public void onExternalCollision() {
                    CollisionExternalListener lsnr = extLsnr.get();

                    if (lsnr != null)
                        lsnr.onExternalCollision();
                }
            });
        }
        else
            log.info("Collision resolution is disabled (all jobs will be activated upon arrival).");

        if (log.isDebugEnabled())
            log.debug(startInfo());
    }

    /** {@inheritDoc} */
    @Override public void stop(boolean cancel) throws IgniteCheckedException {
        stopSpi();

        // Unsubscribe.
        if (enabled())
            getSpi().setExternalCollisionListener(null);

        if (log.isDebugEnabled())
            log.debug(stopInfo());
    }

    /**
     * Unsets external collision listener.
     */
    public void unsetCollisionExternalListener() {
        if (enabled())
            getSpi().setExternalCollisionListener(null);
    }

    /**
     * @param lsnr Listener to external collision events.
     */
    public void setCollisionExternalListener(@Nullable CollisionExternalListener lsnr) {
        if (enabled()) {
            if (lsnr != null && !extLsnr.compareAndSet(null, lsnr))
                assert false : "Collision external listener has already been set " +
                    "(perhaps need to add support for multiple listeners)";
            else if (log.isDebugEnabled())
                log.debug("Successfully set external collision listener: " + lsnr);
        }
    }

    /**
     * Invoke collision SPI.
     *
     * @param waitJobs Collection of waiting jobs.
     * @param activeJobs Collection of active jobs.
     * @param heldJobs Collection of held jobs.
     */
    public void onCollision(
        final Collection<CollisionJobContext> waitJobs,
        final Collection<CollisionJobContext> activeJobs,
        final Collection<CollisionJobContext> heldJobs
    ) {<FILL_FUNCTION_BODY>}
}

        if (enabled()) {
            if (log.isDebugEnabled())
                log.debug("Resolving job collisions [waitJobs=" + waitJobs + ", activeJobs=" + activeJobs + ']');

            getSpi().onCollision(new CollisionContext() {
                /** {@inheritDoc} */
                @Override public Collection<CollisionJobContext> activeJobs() {
                    return activeJobs;
                }

                /** {@inheritDoc} */
                @Override public Collection<CollisionJobContext> waitingJobs() {
                    return waitJobs;
                }

                /** {@inheritDoc} */
                @Override public Collection<CollisionJobContext> heldJobs() {
                    return heldJobs;
                }
            });
        }
    
<methods>public void collectGridNodeData(org.apache.ignite.spi.discovery.DiscoveryDataBag) ,public void collectJoiningNodeData(org.apache.ignite.spi.discovery.DiscoveryDataBag) ,public org.apache.ignite.internal.GridComponent.DiscoveryDataExchangeType discoveryDataType() ,public boolean enabled() ,public void onAfterSpiStart() ,public void onBeforeSpiStart() ,public void onDisconnected(IgniteFuture<?>) throws org.apache.ignite.IgniteCheckedException,public void onGridDataReceived(org.apache.ignite.spi.discovery.DiscoveryDataBag.GridDiscoveryData) ,public void onJoiningNodeDataReceived(org.apache.ignite.spi.discovery.DiscoveryDataBag.JoiningNodeDiscoveryData) ,public final void onKernalStart(boolean) throws org.apache.ignite.IgniteCheckedException,public final void onKernalStop(boolean) ,public IgniteInternalFuture<?> onReconnected(boolean) throws org.apache.ignite.IgniteCheckedException,public void printMemoryStats() ,public final java.lang.String toString() ,public org.apache.ignite.spi.IgniteNodeValidationResult validateNode(org.apache.ignite.cluster.ClusterNode) ,public org.apache.ignite.spi.IgniteNodeValidationResult validateNode(org.apache.ignite.cluster.ClusterNode, org.apache.ignite.spi.discovery.DiscoveryDataBag.JoiningNodeDiscoveryData) <variables>protected final non-sealed org.apache.ignite.internal.GridKernalContext ctx,private final non-sealed boolean enabled,private boolean injected,protected final non-sealed org.apache.ignite.IgniteLogger log,private final Map<org.apache.ignite.spi.IgniteSpi,java.lang.Boolean> spiMap,private final non-sealed org.apache.ignite.spi.collision.CollisionSpi[] spis