/// <summary>
        /// Perform a lock or unlock operation on a tag. The first tag seen
        /// is operated on - the singulation parameter may be used to control
        /// this. Note that a tag without an access password set may not
        /// accept a lock operation or remain locked.
        /// </summary>
        /// <param name="target">the tag target to operate on</param>
        /// <param name="action">the tag lock action</param>
        public override void LockTag(TagFilter target, TagLockAction action)
        {
            PrepForTagop();
            TagProtocol protocol = (TagProtocol) ParamGet("/reader/tagop/protocol");

            if (action is Gen2.LockAction)
            {
                if (TagProtocol.GEN2 != protocol)
                {
                    throw new ArgumentException(String.Format(
                        "Gen2.LockAction not compatible with protocol {0}",
                        protocol.ToString()));
                }

                Gen2.LockAction la = (Gen2.LockAction) action;

                // TODO: M4API makes a distinction between locking tag ID and data.
                // Locking tag_id allows access to only the EPC, TID and password banks.
                // Locking tag_data allows access to only the User bank.
                // Ideally, M4API would stop making the distinction, since Gen2 has a unified locking model.
                // In the meantime, just lock tag_id, since it covers more and tags with user memory are still uncommon.

                if ((la.Mask & 0x3FC) != 0)
                    SetField("tag_id.locked", new Gen2LockArgs(target, (Gen2.LockAction) action));

                else if ((la.Mask & 0x3) != 0)
                    SetField("tag_data.locked", new Gen2LockArgs(target, (Gen2.LockAction) action));
            }
            else
                throw new ArgumentException("LockTag does not support this type of TagLockAction: " + action.ToString());
        }
        /// <summary>
        /// Perform a lock or unlock operation on a tag. The first tag seen
        /// is operated on - the singulation parameter may be used to control
        /// this. Note that a tag without an access password set may not
        /// accept a lock operation or remain locked.
        /// </summary>
        /// <param name="target">the tag target to operate on</param>
        /// <param name="action">the tag lock action</param>
        public override void LockTag(TagFilter target, TagLockAction action)
        {
            TagProtocol protocol = (TagProtocol)ParamGet("/reader/tagop/protocol");

            if (action is Gen2.LockAction)
            {
                if (TagProtocol.GEN2 != protocol)
                {
                    throw new ArgumentException(String.Format(
                        "Gen2.LockAction not compatible with protocol {0}",
                        protocol.ToString()));
                }

                Gen2.LockAction la = (Gen2.LockAction)action;
                Gen2.Password pwobj = (Gen2.Password)ParamGet("/reader/gen2/accessPassword");
                UInt32 accessPassword = pwobj.Value;
                ExecuteTagOp(new Gen2.Lock(accessPassword, la), target);
            }
            else if (action is Iso180006b.LockAction)
            {
                if (TagProtocol.ISO180006B != protocol)
                {
                    throw new ArgumentException(String.Format(
                        "Iso180006b.LockAction not compatible with protocol {0}",
                        protocol.ToString()));
                }

                Iso180006b.LockAction i18kaction = (Iso180006b.LockAction)action;
                ExecuteTagOp(new Iso180006b.LockTag(i18kaction.Address), target);
            }
            else
            {
                throw new ArgumentException("LockTag does not support this type of TagLockAction: " + action.ToString());
            }
        }