class ContentionClosure implements IgniteCallable<ContentionInfo> {
    /** Serial version uid. */
    private static final long serialVersionUID = 0L;

    /** Ignite. */
    @IgniteInstanceResource
    protected transient IgniteEx ignite;

    /** */
    private int minQueueSize;

    /** */
    private int maxPrint;

    /**
     * @param minQueueSize Min candidate queue size to account.
     * @param maxPrint Max entries to print.
     */
    public ContentionClosure(int minQueueSize, int maxPrint) {
        this.minQueueSize = minQueueSize;
        this.maxPrint = maxPrint;
    }

    /** {@inheritDoc} */
    @Override public ContentionInfo call() throws Exception {<FILL_FUNCTION_BODY>}
}

        final IgniteTxManager tm = ignite.context().cache().context().tm();

        final Collection<IgniteInternalTx> activeTxs = tm.activeTransactions();

        ContentionInfo ci = new ContentionInfo();

        ci.setNode(ignite.localNode());
        ci.setEntries(new ArrayList<>());

        for (IgniteInternalTx tx : activeTxs) {
            if (ci.getEntries().size() == maxPrint)
                break;

            // Show only primary txs.
            if (tx.local()) {
                IgniteTxLocalAdapter tx0 = (IgniteTxLocalAdapter)tx;

                final IgniteTxLocalState state0 = tx0.txState();

                if (!(state0 instanceof IgniteTxStateImpl))
                    continue;

                final IgniteTxStateImpl state = (IgniteTxStateImpl)state0;

                final Collection<IgniteTxEntry> entries = state.allEntriesCopy();

                IgniteTxEntry bad = null;

                int qSize = 0;

                for (IgniteTxEntry entry : entries) {
                    Collection<GridCacheMvccCandidate> locs;

                    GridCacheEntryEx cached = entry.cached();

                    while (true) {
                        try {
                            locs = cached.localCandidates();

                            break;
                        }
                        catch (GridCacheEntryRemovedException ignored) {
                            cached = entry.context().cache().entryEx(entry.key());
                        }
                    }

                    if (locs != null)
                        qSize += locs.size();

                    final Collection<GridCacheMvccCandidate> rmts = cached.remoteMvccSnapshot();

                    if (rmts != null)
                        qSize += rmts.size();

                    if (qSize >= minQueueSize) {
                        bad = entry;

                        break;
                    }
                    else
                        qSize = 0;
                }

                if (bad != null) {
                    StringBuilder b = new StringBuilder();

                    b.append("TxEntry [cacheId=").append(bad.cacheId()).
                        append(", key=").append(bad.key()).
                        append(", queue=").append(qSize).
                        append(", op=").append(bad.op()).
                        append(", val=").append(bad.value()).
                        append(", tx=").append(CU.txString(tx)).
                        append(", other=[");

                    final IgniteTxState st = tx.txState();

                    if (st instanceof IgniteTxStateImpl) {
                        IgniteTxStateImpl st0 = (IgniteTxStateImpl)st;

                        final Collection<IgniteTxEntry> cp = st0.allEntriesCopy();

                        for (IgniteTxEntry entry : cp) {
                            if (entry == bad)
                                continue;

                            b.append(entry.toString()).append('\n');
                        }
                    }

                    b.append("]]");

                    ci.getEntries().add(b.toString());
                }
            }
        }

        return ci;
    
<no_super_class>