//
        //	Calls applyRotationLocks && applyRotationLimits
        //	This method verifies that the passed value can be set on the
        //	rotate plugs. In the base class, limits as well as locking are
        //	checked by this method.
        //
        //	The compute, validateAndSetValue, and rotateTo functions
        //	all use this method.
        //
        protected override void checkAndSetRotation(MDataBlock block, MPlug plug, MEulerRotation newRotation, MSpace.Space space)
        {
            MDGContext context = block.context;

            updateMatrixAttrs(context);

            MEulerRotation outRotation = newRotation;

            if (context.isNormal)
            {
                //	For easy reading.
                //
                MPxTransformationMatrix xformMat = baseTransformationMatrix;

                //	Get the current translation in transform space for
                //	clamping and locking.
                //
                MEulerRotation savedRotation =
                    xformMat.eulerRotation(MSpace.Space.kTransform);

                //	Translate to transform space, since the limit test needs the
                //	values in transform space. The locking test needs the values
                //	in the same space as the savedR value - which is transform
                //	space as well.
                //
                baseTransformationMatrix.rotateTo(newRotation, space);

                outRotation = xformMat.eulerRotation(MSpace.Space.kTransform);

                //	Now that everything is in the same space, apply limits
                //	and change the value to adhere to plug locking.
                //
                outRotation = applyRotationLimits(outRotation, block);
                outRotation = applyRotationLocks(outRotation, savedRotation);

                //	The value that remain is in transform space.
                //
                xformMat.rotateTo(outRotation, MSpace.Space.kTransform);

                //	Get the value that was just set. It needs to be in transform
                //	space since it is used to set the datablock values at the
                //	end of this method. Getting the vaolue right before setting
                //	ensures that the transformation matrix and data block will
                //	be synchronized.
                //
                outRotation = xformMat.eulerRotation(MSpace.Space.kTransform);
            }
            else
            {
                //	Get the rotation for clamping and locking. This will get the
                //	rotate value in transform space.
                //
                double[]       s3            = block.inputValue(rotate).Double3;
                MEulerRotation savedRotation = new MEulerRotation(s3[0], s3[1], s3[2]);

                //	Create a local transformation matrix for non-normal context
                //	calculations.
                //
                MPxTransformationMatrix local = createTransformationMatrix();
                if (null == local)
                {
                    throw new InvalidOperationException("rockingTransformCheck::checkAndSetRotation internal error");
                }

                //	Fill the newly created transformation matrix.
                //
                computeLocalTransformation(local, block);

                //	Translate the values to transform space. This will allow the
                //	limit and locking tests to work properly.
                //
                local.rotateTo(newRotation, space);

                outRotation = local.eulerRotation(MSpace.Space.kTransform);

                //	Apply limits
                //
                outRotation = applyRotationLimits(outRotation, block);

                outRotation = applyRotationLocks(outRotation, savedRotation);

                local.rotateTo(outRotation, MSpace.Space.kTransform);

                //	Get the rotate value in transform space for placement in the
                //	data block.
                //
                outRotation = local.eulerRotation(MSpace.Space.kTransform);

                local.Dispose();
            }

            MDataHandle handle = block.outputValue(plug);

            if (plug.equalEqual(rotate))
            {
                handle.set(outRotation.x, outRotation.y, outRotation.z);
            }
            else if (plug.equalEqual(rotateX))
            {
                handle.set(outRotation.x);
            }
            else if (plug.equalEqual(rotateY))
            {
                handle.set(outRotation.y);
            }
            else
            {
                handle.set(outRotation.z);
            }

            return;
        }