/**
   * Unmarshalls transfer object from remote node within a given context.
   *
   * @param ctx Grid kernal context that provides deployment and marshalling services.
   * @param sndNodeId {@link UUID} of the sender node.
   * @param msg Transfer object that contains original serialized object and deployment information.
   * @return Unmarshalled object.
   * @throws IgniteCheckedException If node cannot obtain deployment.
   */
  static Object unmarshall(GridKernalContext ctx, UUID sndNodeId, GridAffinityMessage msg)
      throws IgniteCheckedException {
    GridDeployment dep =
        ctx.deploy()
            .getGlobalDeployment(
                msg.deploymentMode(),
                msg.sourceClassName(),
                msg.sourceClassName(),
                msg.userVersion(),
                sndNodeId,
                msg.classLoaderId(),
                msg.loaderParticipants(),
                null);

    if (dep == null)
      throw new IgniteDeploymentCheckedException(
          "Failed to obtain affinity object (is peer class loading turned on?): " + msg);

    Object src =
        U.unmarshal(ctx, msg.source(), U.resolveClassLoader(dep.classLoader(), ctx.config()));

    // Resource injection.
    ctx.resource().inject(dep, dep.deployedClass(msg.sourceClassName()), src);

    return src;
  }
  /**
   * @param ctx {@code GridKernalContext} instance which provides deployment manager
   * @param o Object for which deployment should be obtained.
   * @return Deployment object for given instance,
   * @throws IgniteCheckedException If node cannot create deployment for given object.
   */
  private static GridAffinityMessage affinityMessage(GridKernalContext ctx, Object o)
      throws IgniteCheckedException {
    Class cls = o.getClass();

    GridDeployment dep = ctx.deploy().deploy(cls, cls.getClassLoader());

    if (dep == null)
      throw new IgniteDeploymentCheckedException(
          "Failed to deploy affinity object with class: " + cls.getName());

    return new GridAffinityMessage(
        U.marshal(ctx, o),
        cls.getName(),
        dep.classLoaderId(),
        dep.deployMode(),
        dep.userVersion(),
        dep.participants());
  }
    /**
     * @param nodeId Node ID.
     * @param ctx Kernal context.
     * @return Deserialized object.
     * @throws IgniteCheckedException In case of error.
     */
    <T> T unmarshal(UUID nodeId, GridKernalContext ctx) throws IgniteCheckedException {
      assert ctx != null;

      GridDeployment dep =
          ctx.deploy()
              .getGlobalDeployment(
                  depInfo.deployMode(),
                  clsName,
                  clsName,
                  depInfo.userVersion(),
                  nodeId,
                  depInfo.classLoaderId(),
                  depInfo.participants(),
                  null);

      if (dep == null)
        throw new IgniteDeploymentCheckedException(
            "Failed to obtain deployment for class: " + clsName);

      return ctx.config().getMarshaller().unmarshal(bytes, dep.classLoader());
    }