/// <summary>
        /// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
        /// </summary>
        /// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
        /// <param name="response">The command response in byte array format.</param>
        /// <param name="status">The <see cref="ATCommandStatus"/> containing the response status.</param>
        /// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
        /// <seealso cref="ATCommand"/>
        /// <seealso cref="ATCommandStatus"/>
        public ATCommandResponse(ATCommand command, byte[] response, ATCommandStatus status)
        {
            Contract.Requires<ArgumentNullException>(command != null, "Command cannot be null.");
            Contract.Requires<ArgumentNullException>(status != null, "Status cannot be null.");

            Command = command;
            Response = response;
            Status = status;
        }
		/// <summary>
		/// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
		/// </summary>
		/// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
		/// <param name="response">The command response in byte array format.</param>
		/// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
		/// <seealso cref="ATCommand"/>
		public ATCommandResponse(ATCommand command, byte[] response)
			: this(command, response, ATCommandStatus.OK)
		{
		}
		/// <summary>
		/// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
		/// </summary>
		/// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
		/// <param name="status">The <see cref="ATCommandStatus"/> containing the response status.</param>
		/// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
		/// <seealso cref="ATCommand"/>
		/// <seealso cref="ATCommandStatus"/>
		public ATCommandResponse(ATCommand command, ATCommandStatus status)
			: this(command, null, status)
		{
		}
		/// <summary>
		/// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
		/// </summary>
		/// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
		/// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
		/// <seealso cref="ATCommand"/>
		public ATCommandResponse(ATCommand command)
			: this(command, null, ATCommandStatus.OK)
		{
		}
 /// <summary>
 /// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
 /// </summary>
 /// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
 /// <param name="response">The command response in byte array format.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
 /// <seealso cref="ATCommand"/>
 public ATCommandResponse(ATCommand command, byte[] response)
     : this(command, response, ATCommandStatus.OK)
 {
 }
 /// <summary>
 /// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
 /// </summary>
 /// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
 /// <param name="status">The <see cref="ATCommandStatus"/> containing the response status.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
 /// <seealso cref="ATCommand"/>
 /// <seealso cref="ATCommandStatus"/>
 public ATCommandResponse(ATCommand command, ATCommandStatus status)
     : this(command, null, status)
 {
 }
 /// <summary>
 /// Initializes a new instance of the class <see cref="ATCommandResponse"/>.
 /// </summary>
 /// <param name="command">The <see cref="ATCommand"/> that generated the response.</param>
 /// <exception cref="ArgumentNullException">if <paramref name="command"/> is null or <paramref name="status"/> is null.</exception>
 /// <seealso cref="ATCommand"/>
 public ATCommandResponse(ATCommand command)
     : this(command, null, ATCommandStatus.OK)
 {
 }
		/**
		 * Sends the given AT command and waits for answer or until the configured 
		 * receive timeout expires.
		 * 
		 * <p>The receive timeout is configured using the {@code setReceiveTimeout}
		 * method and can be consulted with {@code getReceiveTimeout} method.</p>
		 * 
		 * @param command AT command to be sent.
		 * @return An {@code ATCommandResponse} object containing the response of 
		 *         the command or {@code null} if there is no response.
		 *         
		 * @throws InterfaceNotOpenException if this device connection is not open.
		 * @throws InvalidOperatingModeException if the operating mode is different 
		 *                                       than {@link OperatingMode#API} and 
		 *                                       {@link OperatingMode#API_ESCAPE}.
		 * @throws IOException if an I/O error occurs while sending the AT command.
		 * @throws ArgumentNullException if {@code command == null}.
		 * @throws TimeoutException if the configured time expires while waiting 
		 *                          for the command reply.
		 * 
		 * @see XBeeDevice#getReceiveTimeout()
		 * @see XBeeDevice#setReceiveTimeout(int)
		 * @see com.digi.xbee.api.models.ATCommand
		 * @see com.digi.xbee.api.models.ATCommandResponse
		 */
		protected ATCommandResponse SendATCommand(ATCommand command)
		/*throws InvalidOperatingModeException, TimeoutException, IOException*/ {
			// Check if command is null.
			if (command == null)
				throw new ArgumentNullException("AT command cannot be null.");
			// Check connection.
			if (!connectionInterface.SerialPort.IsOpen)
				throw new InterfaceNotOpenException();

			ATCommandResponse response = null;
			OperatingMode operatingMode = GetOperatingMode();
			switch (operatingMode)
			{
				case OperatingMode.AT:
				case OperatingMode.UNKNOWN:
				default:
					throw new InvalidOperatingModeException(operatingMode);
				case OperatingMode.API:
				case OperatingMode.API_ESCAPE:
					// Create the corresponding AT command packet depending on if the device is local or remote.
					XBeePacket packet;
					if (IsRemote)
					{
						XBee16BitAddress remote16BitAddress = Get16BitAddress();
						if (remote16BitAddress == null)
							remote16BitAddress = XBee16BitAddress.UNKNOWN_ADDRESS;
						RemoteATCommandOptions remoteATCommandOptions = RemoteATCommandOptions.OPTION_NONE;
						if (IsApplyConfigurationChangesEnabled())
							remoteATCommandOptions |= RemoteATCommandOptions.OPTION_APPLY_CHANGES;
						packet = new RemoteATCommandPacket(GetNextFrameID(), Get64BitAddress(), remote16BitAddress, (byte)remoteATCommandOptions, command.Command, command.Parameter);
					}
					else
					{
						if (IsApplyConfigurationChangesEnabled())
							packet = new ATCommandPacket(GetNextFrameID(), command.Command, command.Parameter);
						else
							packet = new ATCommandQueuePacket(GetNextFrameID(), command.Command, command.Parameter);
					}
					if (command.Parameter == null)
						logger.DebugFormat(ToString() + "Sending AT command '{0}'.", command.Command);
					else
						logger.DebugFormat(ToString() + "Sending AT command '{0} {1}'.", command.Command, HexUtils.PrettyHexString(command.Parameter));
					try
					{
						// Send the packet and build the corresponding response depending on if the device is local or remote.
						XBeePacket answerPacket;
						if (IsRemote)
							answerPacket = localXBeeDevice.SendXBeePacket(packet);
						else
							answerPacket = SendXBeePacket(packet);
						if (answerPacket is ATCommandResponsePacket)
							response = new ATCommandResponse(command, ((ATCommandResponsePacket)answerPacket).CommandValue, ((ATCommandResponsePacket)answerPacket).Status);
						else if (answerPacket is RemoteATCommandResponsePacket)
							response = new ATCommandResponse(command, ((RemoteATCommandResponsePacket)answerPacket).getCommandValue(), ((RemoteATCommandResponsePacket)answerPacket).Status);

						if (response != null && response.Response != null)
							logger.DebugFormat(ToString() + "AT command response: {0}.", HexUtils.PrettyHexString(response.Response));
						else
							logger.Debug(ToString() + "AT command response: null.");
					}
					catch (InvalidCastException e)
					{
						logger.Error("Received an invalid packet type after sending an AT command packet." + e);
					}
					break;
			}
			return response;
		}
		/**
		 * Sends the given AT parameter to this XBee device with an optional 
		 * argument or value and returns the response (likely the value) of that 
		 * parameter in a byte array format.
		 * 
		 * @param parameter The name of the AT command to be executed.
		 * @param parameterValue The value of the parameter to set (if any).
		 * 
		 * @return A byte array containing the value of the parameter.
		 * 
		 * @throws ArgumentException if {@code parameter.length() != 2}.
		 * @throws ArgumentNullException if {@code parameter == null}.
		 * @throws TimeoutException if there is a timeout executing the parameter.
		 * @throws XBeeException if there is any other XBee related exception.
		 * 
		 * @see #getParameter(String)
		 * @see #executeParameter(String)
		 * @see #setParameter(String, byte[])
		 */
		private byte[] SendParameter(string parameter, byte[] parameterValue)/*throws TimeoutException, XBeeException */{
			if (parameter == null)
				throw new ArgumentNullException("Parameter cannot be null.");
			if (parameter.Length != 2)
				throw new ArgumentException("Parameter must contain exactly 2 characters.");

			ATCommand atCommand = new ATCommand(parameter, parameterValue);

			// Create and send the AT Command.
			ATCommandResponse response = null;
			try
			{
				response = SendATCommand(atCommand);
			}
			catch (IOException e)
			{
				throw new XBeeException("Error writing in the communication interface.", e);
			}

			// Check if AT Command response is valid.
			CheckATCommandResponseIsValid(response);

			// Return the response value.
			return response.Response;
		}