class MetadataRemoveJob extends VisorJob<MetaRemoveCommandArg, MetadataMarshalled> {
        /** */
        private static final long serialVersionUID = 0L;

        /** Auto-inject job context. */
        @JobContextResource
        private transient ComputeJobContext jobCtx;

        /** Metadata future. */
        private transient IgniteInternalFuture<?> future;

        /** Job result: metadata info for removed type (used for job continuation). */
        private transient MetadataMarshalled res;

        /**
         * @param arg Argument.
         * @param debug Debug.
         */
        protected MetadataRemoveJob(@Nullable MetaRemoveCommandArg arg, boolean debug) {
            super(arg, debug);
        }

        /** {@inheritDoc} */
        @Override public SecurityPermissionSet requiredPermissions() {
            return systemPermissions(ADMIN_METADATA_OPS);
        }

        /** {@inheritDoc} */
        @Override protected MetadataMarshalled run(@Nullable MetaRemoveCommandArg arg) throws IgniteException {<FILL_FUNCTION_BODY>}
    }

            try {
                if (future == null) {
                    assert Objects.nonNull(arg);

                    int typeId = typeId(ignite.context(), arg.typeId(), arg.typeName());

                    BinaryMetadata meta = ((CacheObjectBinaryProcessorImpl)ignite.context().cacheObjects())
                        .binaryMetadata(typeId);

                    if (meta == null)
                        return new MetadataMarshalled(null, null);

                    byte[] marshalled = U.marshal(ignite.context(), meta);

                    res = new MetadataMarshalled(marshalled, meta);

                    ignite.context().cacheObjects().removeType(typeId);

                    future = ignite.context().closure().runAsync(
                        BROADCAST,
                        new DropAllThinSessionsJob(),
                        options(ignite.cluster().forServers().nodes())
                    );

                    jobCtx.holdcc();

                    future.listen(() -> {
                        if (future.isDone())
                            jobCtx.callcc();
                    });

                    return null;
                }

                return res;
            }
            catch (IgniteCheckedException e) {
                throw new IgniteException(e);
            }
        
<methods>public non-sealed void <init>() ,public Map<? extends org.apache.ignite.compute.ComputeJob,org.apache.ignite.cluster.ClusterNode> map(List<org.apache.ignite.cluster.ClusterNode>, VisorTaskArgument<org.apache.ignite.internal.management.meta.MetaRemoveCommandArg>) ,public final org.apache.ignite.internal.management.meta.MetadataMarshalled reduce(List<org.apache.ignite.compute.ComputeJobResult>) ,public org.apache.ignite.compute.ComputeJobResultPolicy result(org.apache.ignite.compute.ComputeJobResult, List<org.apache.ignite.compute.ComputeJobResult>) <variables>protected boolean debug,protected transient org.apache.ignite.internal.IgniteEx ignite,protected long start,protected org.apache.ignite.internal.management.meta.MetaRemoveCommandArg taskArg