gt: 				id += clean(cu.getPackage().getName().getFullyQualifiedName()
context: package de.ovgu.cide.language.jdt;
  
  import java.io.Serializable;
  import java.util.Collections;
  import java.util.List;
  import java.util.Map;
  import java.util.WeakHashMap;
  
  import org.eclipse.jdt.core.dom.ASTNode;
  import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
  import org.eclipse.jdt.core.dom.ArrayInitializer;
  import org.eclipse.jdt.core.dom.Block;
  import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor;
  import org.eclipse.jdt.core.dom.ClassInstanceCreation;
  import org.eclipse.jdt.core.dom.CompilationUnit;
  import org.eclipse.jdt.core.dom.ConstructorInvocation;
  import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
  import org.eclipse.jdt.core.dom.EnumDeclaration;
  import org.eclipse.jdt.core.dom.FieldDeclaration;
  import org.eclipse.jdt.core.dom.ITypeBinding;
  import org.eclipse.jdt.core.dom.ImportDeclaration;
  import org.eclipse.jdt.core.dom.InfixExpression;
  import org.eclipse.jdt.core.dom.MethodDeclaration;
  import org.eclipse.jdt.core.dom.MethodInvocation;
  import org.eclipse.jdt.core.dom.Name;
  import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
  import org.eclipse.jdt.core.dom.SuperConstructorInvocation;
  import org.eclipse.jdt.core.dom.SuperMethodInvocation;
  import org.eclipse.jdt.core.dom.SwitchStatement;
  import org.eclipse.jdt.core.dom.TryStatement;
  import org.eclipse.jdt.core.dom.Type;
  import org.eclipse.jdt.core.dom.TypeDeclaration;
  import org.eclipse.jdt.core.dom.VariableDeclaration;
  import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
  
  public class ASTID implements Serializable {
  
  	private static final long serialVersionUID = 1L;
  
  	public final String id;
  
  	private ASTID(ASTNode node) {
  		this.id = calculateId(node);
  	}
  
  	private ASTID(ASTNode node, boolean old) {
  		if (old)
  			this.id = calculateId_old(node);
  		else
  			this.id = calculateId(node);
  	}
  
  	// private static String convertToHex(byte[] data) {
  	// StringBuffer buf = new StringBuffer();
  	// for (int i = 0; i < data.length; i++) {
  	// int halfbyte = (data[i] >>> 4) & 0x0F;
  	// int two_halfs = 0;
  	// do {
  	// if ((0 <= halfbyte) && (halfbyte <= 9))
  	// buf.append((char) ('0' + halfbyte));
  	// else
  	// buf.append((char) ('a' + (halfbyte - 10)));
  	// halfbyte = data[i] & 0x0F;
  	// } while (two_halfs++ < 1);
  	// }
  	// return buf.toString();
  	// }
  	//
  	// public static String MD5(String text) {
  	// try {
  	// MessageDigest md;
  	// md = MessageDigest.getInstance("MD5");
  	// byte[] md5hash = new byte[32];
  	// md.update(text.getBytes("iso-8859-1"), 0, text.length());
  	// md5hash = md.digest();
  	// return convertToHex(md5hash);
  	// } catch (UnsupportedEncodingException e) {
  	// e.printStackTrace();
  	// return text;
  	// } catch (NoSuchAlgorithmException e) {
  	// e.printStackTrace();
  	// return text;
  	// }
  	// }
  
  	// private ASTID(String id) {
  	// this.id = id;
  	// }
  
  	private static final Map<ASTNode, ASTID> cache = Collections
  			.synchronizedMap(new WeakHashMap<ASTNode, ASTID>());
  
  	public static String id(ASTNode node) {
  		ASTID id = cache.get(node);
  		if (id == null) {
  			id = new ASTID(node);
  			cache.put(node, id);
  		}
  		return id.id;
  	}
  
  	public static ASTID id_old(ASTNode node) {
  		return new ASTID(node, true);
  	}
  
  	private static String clean(String str) {
  		str = str.replace('/', '_');
  		return str.replace(':', '_');
  	}
  
  	public static String calculateId(ASTNode node) {
  		if (node == null)
  			return "/";
  		String id = calculateId(node.getParent());
  
  		if (node.getParent() instanceof Block) {
  			Block block = (Block) node.getParent();
  			int idx = block.statements().indexOf(node);
  			id += "[" + idx + "]";
  		}
  		if (node.getParent() instanceof ArrayInitializer) {
  			ArrayInitializer block = (ArrayInitializer) node.getParent();
  			int idx = block.expressions().indexOf(node);
  			id += "[" + idx + "]";
  		}
  		if (node.getLocationInParent() != null && node.getParent() != null) {
  			id += ":" + node.getLocationInParent().getId();
  		}
  		if (node.getParent() instanceof TryStatement) {
  			TryStatement trystmt = (TryStatement) node.getParent();
  			if (trystmt.getBody() == node)
  				id += "[body]";
  		}
  		// if (node.getLocationInParent() instanceof
  		// ChildListPropertyDescriptor) {
  		// List children = (List) node.getParent().getStructuralProperty(
  		// node.getLocationInParent());
  		// id += "[" + children.indexOf(node) + "]";
  		// }
  
  		id += "/" + clean(node.getClass().getSimpleName());
  
  		if (node instanceof TypeDeclaration) {
  			id += ":" + clean(((TypeDeclaration) node).getName().toString());
  		}
  		if (node instanceof EnumDeclaration) {
  			id += ":" + clean(((EnumDeclaration) node).getName().toString());
  		}
  		if (node instanceof FieldDeclaration) {
  			for (Object fragment : ((FieldDeclaration) node).fragments()) {
  				id += ":"
  						+ clean(((VariableDeclarationFragment) fragment)
  								.getName().toString());
  			}
  		}
  		if (node instanceof Type) {
  			ITypeBinding b = ((Type) node).resolveBinding();
  			id += "::" + (b == null ? "null" : b.getQualifiedName());
  		}
  		if (node instanceof VariableDeclaration)
  			id += ":"
  					+ clean(((VariableDeclaration) node).getName().toString());
  		if (node instanceof EnumConstantDeclaration)
  			id += ":"
  					+ clean(((EnumConstantDeclaration) node).getName()
  							.toString());
  		if (node instanceof Name)
  			id += ":" + clean(((Name) node).getFullyQualifiedName());
  		if (node instanceof ImportDeclaration)
  			id += ":" + clean(((ImportDeclaration) node).getName().toString());
  		if (node instanceof MethodDeclaration) {
  			Type rt = ((MethodDeclaration) node).getReturnType2();
  			id += ":" + clean(rt == null ? "void" : rt.toString());
  			id += ":" + clean(((MethodDeclaration) node).getName().toString());
  			id += ":"
  					+ clean(getParameterTypes(((MethodDeclaration) node)
  							.parameters()));
  		}
  
  		ChildListPropertyDescriptor[] enumLists = new ChildListPropertyDescriptor[] {
  				SwitchStatement.STATEMENTS_PROPERTY,
  				InfixExpression.EXTENDED_OPERANDS_PROPERTY,
  				TryStatement.CATCH_CLAUSES_PROPERTY,
  				MethodInvocation.ARGUMENTS_PROPERTY,
  				ConstructorInvocation.ARGUMENTS_PROPERTY,
  				ClassInstanceCreation.ARGUMENTS_PROPERTY,
  				SuperConstructorInvocation.ARGUMENTS_PROPERTY,
  				SuperMethodInvocation.ARGUMENTS_PROPERTY };
  		for (ChildListPropertyDescriptor prop : enumLists) {
  			if (node.getLocationInParent() == prop) {
  				List<?> childList = (List<?>) node.getParent()
  						.getStructuralProperty(prop);
  				int idx = childList.indexOf(node);
  				id += "[" + idx + "]";
  			}
  		}
  
  		if (node instanceof CompilationUnit) {
  			// IJavaElement je = ((CompilationUnit) node).getJavaElement();
  			CompilationUnit cu = ((CompilationUnit) node);
  			id += "[";
  			if (cu.getPackage() != null && cu.getPackage().getName() != null)
  