va_start(args, paramStart);
		CFTypeRef key, value;
		for (uint32_t i = 0; i < argsCount; i++) {
			key = va_arg(args, CFTypeRef);
			value = va_arg(args, CFTypeRef);
			CFDictionarySetValue(message, key, value);
			i++;
		}
		va_end(args);
		SocketConnection sock;
		if (conn->ivars.ssl)
			sock = (SocketConnection){true, {.ssl = conn->ivars.ssl}};
		else
			sock = (SocketConnection){false, {.conn = conn->ivars.socket}};
			
		result = SDMMD_ServiceSendStream(sock, message, kCFPropertyListXMLFormat_v1_0);
		if (result == 0) {
			CFDictionaryRef response = NULL;
			result = SDMMD_ServiceReceiveStream(sock, (CFPropertyListRef*)&response);
			if (result == 0 && response) {
				while (result == 0) {
					CFTypeRef error = CFDictionaryGetValue(response, CFSTR("Error"));
					if (error) {
						CFShow(response);
						result = SDMMD__ConvertServiceError(error);
						printf("call_and_response: GOT AN ERROR 0x%08x %s.\n",result, SDMMD_AMDErrorString(result));
					} else {
						CFTypeRef status = CFDictionaryGetValue(response, CFSTR("Status"));
						if (status) {
							if (CFStringCompare(status, CFSTR("Complete"), 0) != 0) {
								CFArrayRef responses = CFDictionaryGetValue(response, CFSTR("CurrentList"));
sdmmd_return_t SDMMD_perform_command(SDMMD_AMConnectionRef conn, CFStringRef command, uint64_t code, CallBack handle, uint32_t argsCount, void* paramStart, ...) {
	sdmmd_return_t result = kAMDSuccess;
	CFMutableDictionaryRef message = SDMMD_create_dict();
	
	if (message) {
		va_list args;

		CFDictionarySetValue(message, CFSTR("Command"), command);
		va_start(args, paramStart);
		CFTypeRef key, value;
		for (uint32_t i = 0; i < argsCount; i++) {
			key = va_arg(args, CFTypeRef);
			value = va_arg(args, CFTypeRef);
			CFDictionarySetValue(message, key, value);
			i++;
		}
		va_end(args);

		SocketConnection sock = SDMMD_TranslateConnectionToSocket(conn);
		result = SDMMD_ServiceSendStream(sock, message, kCFPropertyListXMLFormat_v1_0);
		CFSafeRelease(message);
		if (result == 0) {
			CFDictionaryRef response = NULL;
			result = SDMMD_ServiceReceiveStream(sock, (CFPropertyListRef*)&response);
			if (result == 0 && response) {
				while (result == 0) {
					result = SDMMD__ErrorHandler(SDMMD__ConvertServiceError, response);
					
					CheckErrorAndReturn(result);
					
					CFTypeRef status = CFDictionaryGetValue(response, CFSTR("Status"));
					if (status) {
						if (CFStringCompare(status, CFSTR("Complete"), 0) != 0) {
							CFArrayRef responses = CFDictionaryGetValue(response, CFSTR("CurrentList"));
							if (responses) {
								uint64_t count = CFArrayGetCount(responses);
								for (uint32_t i = 0; i < count; i++) {
									CFDictionaryRef value = CFArrayGetValueAtIndex(responses, i);
									handle(value, paramStart);
								}
							}
							else {
								handle(response, 0);
							}
						}
						else {
							break;
						}
					}
					SDMMD_ServiceReceiveStream(sock, (CFPropertyListRef*)&response);
				}
			}
			else {
				result = kAMDReceiveMessageError;
				printf("call_and_response: Could not receive response from proxy.\n");
			}
		}
		else {
			result = kAMDSendMessageError;
			printf("call_and_response: Could not send request to proxy.\n");
		}
	}
	else {
		result = kAMDUndefinedError;
	}
	
	ExitLabelAndReturn(result);
}