public String generateMessageString() {
		if (outputMessage == null || isChanged) {
			// Parameters
			StringBuilder content = new StringBuilder(2048);
			for (Map.Entry<String, String> e : this.parameters.entrySet()) {
				if (e.getValue() != null)
					content.append(e.getKey()).append('=')
							.append(urlEncodeUtf16le(e.getValue())).append('&');
			}
			if (this.parameters.size() > 0)
				content.deleteCharAt(content.length() - 1);

			StringBuilder str = new StringBuilder(3560);
			switch (method) {
			case GET:
				// set content type: utf-16le
				this.setHeader(STRING_CONTENTTYPE, STRING_CONTENTTYPE_VALUE);

				str.append(method.toString()).append(' ').append(url)
						.append(content.toString()).append(" HTTP/1.1")
						.append(STRING_CRLF);
				for (Map.Entry<String, String> e : this.headers.entrySet()) {
					str.append(e.getKey()).append(": ").append(e.getValue())
							.append(STRING_CRLF);
				}

				// str.append(STRING_CRLF).append(STRING_CRLF);
				// yangyang:here should end with only one CRLF
				str.append(STRING_CRLF);
				outputMessage = str.toString();
				break;

			case POST:
				// add LRCF size: 2
				// yangyang:the content end have no CRLF here,why + 2?
				// this.setHeader(STRING_CONTENTLENGTH,
				// Integer.toString(content.length() + 2));
				this.setHeader(STRING_CONTENTLENGTH,
						Integer.toString(content.length()));
				// set content type: utf-16le
				this.setHeader(STRING_CONTENTTYPE, STRING_CONTENTTYPE_VALUE);

				str.append(method.toString()).append(' ').append(url)
						.append(" HTTP/1.1").append(STRING_CRLF);
				for (Map.Entry<String, String> e : this.headers.entrySet()) {
					str.append(e.getKey()).append(": ").append(e.getValue())
							.append(STRING_CRLF);
				}
				str.append(STRING_CRLF);
				str.append(content.toString());
				outputMessage = str.toString();
				break;
			}
		}
		return outputMessage;
	}