private String toExpectedGraph(String graphTestDSL) {
		StringBuilder s = new StringBuilder();
		s.append("{");
		s.append("\"nodes\":[");
		StringTokenizer st = new StringTokenizer(graphTestDSL, ",");
		boolean onLinksNow = false;
		int counter = 0;
		while (st.hasMoreElements()) {
			String element = st.nextToken();
			StringTokenizer elementTokenizer = new StringTokenizer(element, ":");
			String type = elementTokenizer.nextToken();
			if (type.equals("n")) {
				String nodeId = elementTokenizer.nextToken();
				String nodeName = elementTokenizer.nextToken();
				if (counter > 0) {
					s.append(",");
				}
				s.append("{\"id\":\"" + nodeId + "\",\"name\":\"" + nodeName + "\"");
				if (elementTokenizer.hasMoreTokens()) {
					String propertiesAndMetadata = elementTokenizer.nextToken();

					StringBuilder metadata = new StringBuilder();
					StringBuilder properties = new StringBuilder();

					StringTokenizer propertyOrMetadataTokenizer = new StringTokenizer(propertiesAndMetadata, ";");
					metadata.append(",\"metadata\":{");
					properties.append(",\"properties\":{");
					int propertyCount = 0;
					int metadataCount = 0;
					while (propertyOrMetadataTokenizer.hasMoreTokens()) {
						String propertyOrMetadata = propertyOrMetadataTokenizer.nextToken();
						int equals = propertyOrMetadata.indexOf("=");
						String key = propertyOrMetadata.substring(0, equals);
						String value = propertyOrMetadata.substring(equals + 1);
						if (key.startsWith("meta-")) {
							key = key.substring(5);
							if (metadataCount > 0) {
								metadata.append(",");
							}
							metadata.append("\"" + key + "\":\"" + value + "\"");
							metadataCount++;
						}
						else {
							if (propertyCount > 0) {
								s.append(",");
							}
							properties.append("\"" + key + "\":\"" + value + "\"");
							propertyCount++;
						}
					}
					if (metadataCount > 0) {
						s.append(metadata.toString()).append("}");
					}
					if (propertyCount > 0) {
						s.append(properties.toString());
					}
					s.append("}");
				}
				s.append("}");
			}
			else {
				if (!onLinksNow) {
					s.append("],\"links\":[");
					onLinksNow = true;
					counter = 0;
				}
				if (counter > 0) {
					s.append(",");
				}
				String sourceId = elementTokenizer.nextToken();
				String targetId = elementTokenizer.nextToken();
				s.append("{\"from\":\"" + sourceId + "\",\"to\":\"" + targetId + "\"");
				if (elementTokenizer.hasMoreTokens()) {
					String properties = elementTokenizer.nextToken();
					StringTokenizer propertyTokenizer = new StringTokenizer(properties, ";");
					s.append(",\"properties\":{");
					int propertyCount = 0;
					while (propertyTokenizer.hasMoreTokens()) {
						if (propertyCount > 0) {
							s.append(",");
						}
						String property = propertyTokenizer.nextToken();
						int equals = property.indexOf("=");
						String key = property.substring(0, equals);
						String value = property.substring(equals + 1);
						s.append("\"" + key + "\":\"" + value + "\"");
					}
					s.append("}");
				}
				s.append("}");
			}
			counter++;
		}
		s.append("]}");
		return s.toString();
	}
Convert the supplied internal DSL (for test usage only) into a graph against which we can
compare the actual output from the graph creation code.
@param graphTestDSL the shorthand DSL for a graph description
@return a JSON string representing the complete graph
spring-xd-dirt/src/test/java/org/springframework/xd/dirt/job/dsl/JobParserTests.java