private void performPrint(String className, String varName, boolean dump) {
		if (className != null) {
			final ReferenceType clazz = findClass(className);
			final Field f = clazz.fieldByName(varName);
			if (f == null) {
				print(NO_FIELD, varName, className);
			} else if (f.isStatic()) {
				final String value = valueToString(clazz.getValue(f), dump);
				print(VAR, f.typeName(), f.name(), value);
			} else {
				print(FIELD, f.typeName(), className + "." + f.name());
			}
			return;
		}
		// className = null
		try {
			final StackFrame curFrame = curThread.frame(0);
			LocalVariable var = curFrame.visibleVariableByName(varName);
			if (var != null) {
				// local variable
				String value = valueToString(curFrame.getValue(var), dump);
				print(VAR, var.typeName(), var.name(), value);
				return;
			}
			final ReferenceType type = curFrame.location().declaringType();
			final Field f = type.fieldByName(varName);
			if (f == null) {
				print(UNKNOWN, varName);
				return;
			}
			// instance variable of static method
			Value val;
			if (curFrame.location().method().isStatic()) {
				final List<ObjectReference> instances = type.instances(0);
				if (instances.size() == 0) {
					// class not yet initiated
					print(FIELD, f.typeName(), f.name());
					return;
				}
				// class already initiated
				assert instances.size() == 1;
				val = instances.get(0).getValue(f);
			} else {
				val = curFrame.thisObject().getValue(f);
			}
			print(VAR, f.typeName(), f.name(), valueToString(val, dump));
		} catch (IncompatibleThreadStateException e) {
			e.printStackTrace();
		} catch (AbsentInformationException e) {
			print(UNKNOWN, varName);
		}
	}