private boolean sendGridlet(String errorMsg, int gridletId, int userId,
                           int resourceId, double delay, int tag, boolean ack)
    {
        boolean valid = validateValue(errorMsg, gridletId, userId, resourceId);
        if (!valid || delay < 0.0) {
            return false;
        }

        int size = 14;  // size of having 3 ints + 2 bytes overhead
        int[] array = new int[ARRAY_SIZE];
        array[0] = gridletId;
        array[1] = userId;
        array[2] = NOT_FOUND;  // this index is only used by gridletMove()

        // if an ack is required, then change the tag
        int newTag = tag;
        if (ack)
        {
            switch (tag)
            {
                case GridSimTags.GRIDLET_PAUSE:
                    newTag = GridSimTags.GRIDLET_PAUSE_ACK;
                    break;

                case GridSimTags.GRIDLET_RESUME:
                    newTag = GridSimTags.GRIDLET_RESUME_ACK;
                    break;

                default:
                    break;
            }
        }

        // send this Gridlet
        send(super.output, delay, newTag, new IO_data(array, size, resourceId));
        return true;
    }