/**
   * Copies the properties of a specific <tt>DatagramPacket</tt> to another <tt>DatagramPacket</tt>.
   * The property values are not cloned.
   *
   * @param src the <tt>DatagramPacket</tt> which is to have its properties copied to <tt>dest</tt>
   * @param dest the <tt>DatagramPacket</tt> which is to have its properties set to the value of the
   *     respective properties of <tt>src</tt>
   */
  public static void copy(DatagramPacket src, DatagramPacket dest) {
    synchronized (dest) {
      dest.setAddress(src.getAddress());
      dest.setPort(src.getPort());

      byte[] srcData = src.getData();

      if (srcData == null) dest.setLength(0);
      else {
        byte[] destData = dest.getData();

        if (destData == null) dest.setLength(0);
        else {
          int destOffset = dest.getOffset();
          int destLength = destData.length - destOffset;
          int srcLength = src.getLength();

          if (destLength >= srcLength) destLength = srcLength;
          else if (logger.isLoggable(Level.WARNING)) {
            logger.log(Level.WARNING, "Truncating received DatagramPacket data!");
          }
          System.arraycopy(srcData, src.getOffset(), destData, destOffset, destLength);
          dest.setLength(destLength);
        }
      }
    }
  }
  /**
   * Initializes a new <tt>DatagramPacket</tt> instance which is a clone of a specific
   * <tt>DatagramPacket</tt> i.e. the properties of the clone <tt>DatagramPacket</tt> are clones of
   * the specified <tt>DatagramPacket</tt>.
   *
   * @param p the <tt>DatagramPacket</tt> to clone
   * @return a new <tt>DatagramPacket</tt> instance which is a clone of the specified
   *     <tt>DatagramPacket</tt>
   */
  public static DatagramPacket clone(DatagramPacket p) {
    synchronized (p) {
      byte[] pData = p.getData();
      byte[] cData = (pData == null) ? null : pData.clone();

      return new DatagramPacket(cData, p.getOffset(), p.getLength(), p.getAddress(), p.getPort());
    }
  }