/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.ui;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IDebugEventSetListener;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchesListener;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.IValueDetailListener;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.debug.core.IEvaluationRunnable;
import org.eclipse.jdt.debug.core.IJavaArray;
import org.eclipse.jdt.debug.core.IJavaArrayType;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaDebugTarget;
import org.eclipse.jdt.debug.core.IJavaInterfaceType;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaPrimitiveValue;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaStackFrame;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.eval.IAstEvaluationEngine;
import org.eclipse.jdt.debug.eval.ICompiledExpression;
import org.eclipse.jdt.debug.eval.IEvaluationListener;
import org.eclipse.jdt.debug.eval.IEvaluationResult;
import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin;
import org.eclipse.jdt.internal.debug.core.JavaDebugUtils;
import org.eclipse.jdt.internal.debug.core.logicalstructures.JDIAllInstancesValue;
import org.eclipse.jdt.internal.debug.core.model.JDINullValue;
import org.eclipse.jdt.internal.debug.core.model.JDIReferenceListValue;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.osgi.util.NLS;

import com.sun.jdi.InvocationException;

/**
 * Generates strings for the detail pane of views displaying java elements.
 */
public class JavaDetailFormattersManager implements IPropertyChangeListener, IDebugEventSetListener, ILaunchesListener {
	/**
	 * The default detail formatters manager.
	 */
	static private JavaDetailFormattersManager fgDefault;

	/**
	 * Return the default detail formatters manager.
	 *
	 * @return default detail formatters manager.
	 */
	static public JavaDetailFormattersManager getDefault() {
		if (fgDefault == null) {
			fgDefault= new JavaDetailFormattersManager();
		}
		return fgDefault;
	}

	/**
	 * Map of types to the associated formatter (code snippet).
	 * (<code>String</code> -> <code>String</code>)
	 */
	private HashMap<String, DetailFormatter> fDetailFormattersMap;

	/**
	 * Cache of compiled expressions.
	 * Associate a pair type name/debug target to a compiled expression.
	 */
	private HashMap<Key, Expression> fCacheMap;

	/**
	 * JavaDetailFormattersManager constructor.
	 */
	private JavaDetailFormattersManager() {
		populateDetailFormattersMap();
		JDIDebugUIPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(this);
		DebugPlugin.getDefault().getLaunchManager().addLaunchListener(this);
		DebugPlugin.getDefault().addDebugEventListener(this);
		DebugUITools.getPreferenceStore().addPropertyChangeListener(this);
		fCacheMap= new HashMap<>();
	}

	/**
	 * Populate the detail formatters map with data from preferences.
	 */
	private void populateDetailFormattersMap() {
		String[] detailFormattersList= JavaDebugOptionsManager.parseList(JDIDebugUIPlugin.getDefault().getPreferenceStore().getString(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST));
		fDetailFormattersMap= new HashMap<>(detailFormattersList.length / 3);
		for (int i= 0, length= detailFormattersList.length; i < length;) {
			String typeName= detailFormattersList[i++];
			String snippet= detailFormattersList[i++].replace('\u0000', ',');
			boolean enabled= ! JavaDetailFormattersPreferencePage.DETAIL_FORMATTER_IS_DISABLED.equals(detailFormattersList[i++]);
			fDetailFormattersMap.put(typeName, new DetailFormatter(typeName, snippet, enabled));
		}
	}

	/**
	 * Compute asynchronously the 'toString' of the given value. If a formatter is associated to
	 * the type of the given value, this formatter is used instead of the <code>toString()</code>
	 * method.
	 * The result is return through the listener.
	 *
	 * @param objectValue the value to 'format'
	 * @param thread the thread to use to performed the evaluation
	 * @param listener the listener
	 */
	public void computeValueDetail(final IJavaValue objectValue, final IJavaThread thread, final IValueDetailListener listener) {
		thread.queueRunnable(new Runnable() {
			@Override
			public void run() {
				resolveFormatter(objectValue, thread, listener);
			}
		});
	}

	private void resolveFormatter(final IJavaValue value, final IJavaThread thread, final IValueDetailListener listener) {
		EvaluationListener evaluationListener= new EvaluationListener(value, thread, listener);
		if (value instanceof IJavaObject) {
			IJavaObject objectValue= (IJavaObject) value;
			try {
				if(value instanceof JDIAllInstancesValue) {
					listener.detailComputed(value, ((JDIAllInstancesValue)value).getDetailString());
					return;
				}
				if(value instanceof JDIReferenceListValue) {
					listener.detailComputed(value, ((JDIReferenceListValue)value).getDetailString());
					return;
				}
				IJavaDebugTarget debugTarget= (IJavaDebugTarget) thread.getDebugTarget();
				// get the compiled expression to use
				Expression expression= getCompiledExpression(objectValue, debugTarget, thread);
				if (expression != null) {
					expression.getEngine().evaluateExpression(expression.getExpression(), objectValue, thread,
							evaluationListener, DebugEvent.EVALUATION_IMPLICIT, false);
					return;
				}
			} catch (CoreException e) {
				listener.detailComputed(value, e.toString());
				return;
			}
		}
		try {
			evaluationListener.valueToString(value);
		} catch (DebugException e) {
			String detail = e.getStatus().getMessage();
			if (e.getStatus().getException() instanceof UnsupportedOperationException) {
				detail = DebugUIMessages.JavaDetailFormattersManager_7;
			} else if (e.getStatus().getCode() == IJavaThread.ERR_INCOMPATIBLE_THREAD_STATE) {
				detail = DebugUIMessages.JavaDetailFormattersManager_6;
			}
			listener.detailComputed(value, detail);
		}
	}

	private IJavaProject getJavaProject(IJavaObject javaValue, IJavaThread thread) throws CoreException {

		IType type = null;
		if (javaValue instanceof IJavaArray) {
			IJavaArrayType arrType = (IJavaArrayType) javaValue.getJavaType();
			IJavaType compType = arrType.getComponentType();
			while (compType instanceof IJavaArrayType) {
				compType = ((IJavaArrayType)compType).getComponentType();
			}
			type = JavaDebugUtils.resolveType(compType);
		} else {
			type = JavaDebugUtils.resolveType(javaValue);
		}
		if (type != null) {
			return type.getJavaProject();
		}
		IJavaStackFrame stackFrame= null;
		IJavaDebugTarget target = javaValue.getDebugTarget().getAdapter(IJavaDebugTarget.class);
		if (target != null) {
			stackFrame= (IJavaStackFrame) thread.getTopStackFrame();
			if (stackFrame != null && !stackFrame.getDebugTarget().equals(target)) {
				stackFrame= null;
			}
		}
		if (stackFrame == null) {
			return null;
		}
		return JavaDebugUtils.resolveJavaProject(stackFrame);
	}

	/**
	 * Searches the listing of implemented interfaces to see if one of them has a detail formatter
	 * @param type the type whose interfaces you want to inspect
	 * @return an associated details formatter of <code>null</code> if none is found
	 * @since 3.2
	 */
	public DetailFormatter getDetailFormatterFromInterface(IJavaClassType type) {
		try {
			IJavaInterfaceType[] inter = type.getAllInterfaces();
			Object formatter = null;
			for (int i = 0; i < inter.length; i++) {
				formatter = fDetailFormattersMap.get(inter[i].getName());
				if(formatter != null) {
					return (DetailFormatter) formatter;
				}
			}
			return null;
			}
		catch(DebugException e) {return null;}
	}

	/**
	 * Returns if the specified <code>IJavaType</code> has a detail formatter on one of its interfaces
	 * @param type the type to inspect
	 * @return true if there is an existing detail formatter on one of the types' interfaces, false otherwise
	 * @since 3.2
	 */
	public boolean hasInterfaceDetailFormatter(IJavaType type) {
		if(type instanceof IJavaClassType) {
			return getDetailFormatterFromInterface((IJavaClassType) type) != null;
		}
		return false;
	}

	/**
	 * Searches the superclass hierarchy to see if any of the specified classes parents have a detail formatter
	 * @param type the current type. Ideally this should be the first parent class.
	 * @return the first detail formatter located walking up the superclass hierarchy or <code>null</code> if none are found
	 * @since 3.2
	 */
	public DetailFormatter getDetailFormatterFromSuperclass(IJavaClassType type) {
		try {
			if(type == null) {
				return null;
			}
			DetailFormatter formatter = fDetailFormattersMap.get(type.getName());
			if(formatter != null && formatter.isEnabled()) {
				return formatter;
			}
			return getDetailFormatterFromSuperclass(type.getSuperclass());
			}
		catch(DebugException e) {return null;}
	}

	/**
	 * Returns if one of the parent classes of the specified type has a detail formatter
	 * @param type the type to inspect
	 * @return true if one of the parent classes of the type has a detail formatter, false otherwise
	 * @since 3.2
	 */
	public boolean hasSuperclassDetailFormatter(IJavaType type) {
		if(type instanceof IJavaClassType) {
			return getDetailFormatterFromSuperclass((IJavaClassType) type) != null;
		}
		return false;
	}

	public boolean hasAssociatedDetailFormatter(IJavaType type) {
		return getAssociatedDetailFormatter(type) != null;
	}

	public DetailFormatter getAssociatedDetailFormatter(IJavaType type) {
		String typeName = ""; //$NON-NLS-1$
		try {
			while (type instanceof IJavaArrayType) {
				type = ((IJavaArrayType)type).getComponentType();
			}
			if (type instanceof IJavaClassType) {
				typeName = type.getName();
			}
			else {
				return null;
			}
		}
		catch (DebugException e) {return null;}
		return fDetailFormattersMap.get(typeName);
	}

	public void setAssociatedDetailFormatter(DetailFormatter detailFormatter) {
		fDetailFormattersMap.put(detailFormatter.getTypeName(), detailFormatter);
		savePreference();
	}


	private void savePreference() {
		Collection<DetailFormatter> valuesList= fDetailFormattersMap.values();
		String[] values= new String[valuesList.size() * 3];
		int i= 0;
		for (Iterator<DetailFormatter> iter= valuesList.iterator(); iter.hasNext();) {
			DetailFormatter detailFormatter= iter.next();
			values[i++]= detailFormatter.getTypeName();
			values[i++]= detailFormatter.getSnippet().replace(',','\u0000');
			values[i++]= detailFormatter.isEnabled() ? JavaDetailFormattersPreferencePage.DETAIL_FORMATTER_IS_ENABLED : JavaDetailFormattersPreferencePage.DETAIL_FORMATTER_IS_DISABLED;
		}
		String pref = JavaDebugOptionsManager.serializeList(values);
		JDIDebugUIPlugin.getDefault().getPreferenceStore().setValue(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST, pref);
	}

	/**
	 * Return the detail formatter (code snippet) associate with
	 * the given type or one of its super types, super interfaces.
	 * @param type the class type
	 * @return the code snippet for the given type / super type / super interface
	 * @throws DebugException if there is  problem computing the snippet
	 */
	private String getDetailFormatter(IJavaClassType type) throws DebugException {
		String snippet= getDetailFormatterSuperClass(type);
		if (snippet != null) {
			return snippet;
		}
		IJavaInterfaceType[] allInterfaces= type.getAllInterfaces();
		for (int i= 0; i < allInterfaces.length; i++) {
			DetailFormatter detailFormatter= fDetailFormattersMap.get(allInterfaces[i].getName());
			if (detailFormatter != null && detailFormatter.isEnabled()) {
				return detailFormatter.getSnippet();
			}
		}
		return null;
	}

	/**
	 * Return the detail formatter (code snippet) associate with
	 * the given type or one of its super types.
	 * @param type the class type
	 * @return the snippet for the given class / super class
	 * @throws DebugException if there is a problem computing the snippet
	 */
	private String getDetailFormatterSuperClass(IJavaClassType type) throws DebugException {
		if (type == null) {
			return null;
		}
		DetailFormatter detailFormatter= fDetailFormattersMap.get(type.getName());
		if (detailFormatter != null && detailFormatter.isEnabled()) {
			return detailFormatter.getSnippet();
		}
		return getDetailFormatterSuperClass(type.getSuperclass());
	}

	/**
	 * Return the expression which corresponds to the code formatter associated with the type of
	 * the given object or <code>null</code> if none.
	 *
	 * The code snippet is compiled in the context of the given object.
	 * @param javaObject the Java object
	 * @param debugTarget the target
	 * @param thread the thread context
	 * @return the compiled expression to be evaluated
	 * @throws CoreException is a problem occurs compiling the expression
	 */
	private Expression getCompiledExpression(IJavaObject javaObject, IJavaDebugTarget debugTarget, IJavaThread thread) throws CoreException {
		IJavaType type = javaObject.getJavaType();
		if (type == null) {
			return null;
		}
		String typeName = type.getName();
		Key key = new Key(typeName, debugTarget);
		if (fCacheMap.containsKey(key)) {
			return fCacheMap.get(key);
		}
		String snippet = null;
		if (type instanceof IJavaClassType) {
			snippet = getDetailFormatter((IJavaClassType) type);
		} else if (type instanceof IJavaArrayType) {
			snippet = getArraySnippet((IJavaArray) javaObject);
		}
		if (snippet != null) {
			IJavaProject project = getJavaProject(javaObject, thread);
			if (project != null) {
				IAstEvaluationEngine evaluationEngine = JDIDebugPlugin
						.getDefault().getEvaluationEngine(project, debugTarget);
				ICompiledExpression res = evaluationEngine
						.getCompiledExpression(snippet, javaObject);
				if (res != null) {
					Expression exp = new Expression(res, evaluationEngine);
					fCacheMap.put(key, exp);
					return exp;
				}
			}
		}
		return null;
	}

	protected String getArraySnippet(IJavaArray value) throws DebugException {
		String signature = value.getSignature();
		int nesting = Signature.getArrayCount(signature);
		if (nesting > 1) {
			// for nested primitive arrays, print everything
			String sig = Signature.getElementType(signature);
			if (sig.length() == 1 || "Ljava/lang/String;".equals(sig)) { //$NON-NLS-1$
				// return null so we get to "valueToString(IJavaValue)" for primitive and string types
				return null;
			}
		}
		if (((IJavaArrayType)value.getJavaType()).getComponentType() instanceof IJavaReferenceType) {
			int length = value.getLength();
			// guestimate at max entries to print based on char/space/comma per entry
			int maxLength = getMaxDetailLength();
			if (maxLength > 0){
				int maxEntries = (maxLength / 3) + 1;
				if (length > maxEntries) {
					StringBuilder snippet = new StringBuilder();
					snippet.append("Object[] shorter = new Object["); //$NON-NLS-1$
					snippet.append(maxEntries);
					snippet.append("]; System.arraycopy(this, 0, shorter, 0, "); //$NON-NLS-1$
					snippet.append(maxEntries);
					snippet.append("); "); //$NON-NLS-1$
					snippet.append("return java.util.Arrays.asList(shorter).toString();"); //$NON-NLS-1$
					return snippet.toString();
				}
			}
			return "java.util.Arrays.asList(this).toString()"; //$NON-NLS-1$
		}
		return null;
	}

	/**
	 * @see org.eclipse.jface.util.IPropertyChangeListener#propertyChange(PropertyChangeEvent)
	 */
	@Override
	public void propertyChange(PropertyChangeEvent event) {
		String property = event.getProperty();
		if (property.equals(IJDIPreferencesConstants.PREF_DETAIL_FORMATTERS_LIST) ||
				property.equals(IJDIPreferencesConstants.PREF_SHOW_DETAILS) ||
				property.equals(IDebugUIConstants.PREF_MAX_DETAIL_LENGTH)) {
			populateDetailFormattersMap();
			fCacheMap.clear();
			// If a Java stack frame is selected in the Debug view, fire a change event on
			// it so the variables view will update for any formatter changes.
            IAdaptable selected = DebugUITools.getDebugContext();
            if (selected != null) {
                IJavaStackFrame frame= selected.getAdapter(IJavaStackFrame.class);
                if (frame != null) {
                    DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] {
                            new DebugEvent(frame, DebugEvent.CHANGE)
                    });
                }
            }
		}
	}
	/**
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getSource() instanceof IJavaDebugTarget && event.getKind() == DebugEvent.TERMINATE) {
				deleteCacheForTarget((IJavaDebugTarget) event.getSource());
			}
		}
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesAdded(ILaunch[])
	 */
	@Override
	public void launchesAdded(ILaunch[] launches) {
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesChanged(ILaunch[])
	 */
	@Override
	public void launchesChanged(ILaunch[] launches) {
	}

	/**
	 * @see org.eclipse.debug.core.ILaunchesListener#launchesRemoved(ILaunch[])
	 */
	@Override
	public void launchesRemoved(ILaunch[] launches) {
		for (int i = 0; i < launches.length; i++) {
			ILaunch launch = launches[i];
			IDebugTarget[] debugTargets= launch.getDebugTargets();
			for (int j = 0; j < debugTargets.length; j++) {
				if (debugTargets[j] instanceof IJavaDebugTarget) {
					deleteCacheForTarget((IJavaDebugTarget)debugTargets[j]);
				}
			}
		}
	}

	/**
	 * Remove from the cache compiled expression associated with
	 * the given debug target.
	 *
	 * @param debugTarget the target
	 */
	private synchronized void deleteCacheForTarget(IJavaDebugTarget debugTarget) {
		for (Iterator<Key> iter= fCacheMap.keySet().iterator(); iter.hasNext();) {
			Key key= iter.next();
			if ((key).fDebugTarget == debugTarget) {
				iter.remove();
			}
		}
	}

	/**
	 * Object used as the key in the cache map for associate a compiled
	 * expression with a pair type name/debug target
	 */
	static private class Key {
		private String fTypeName;
		private IJavaDebugTarget fDebugTarget;

		Key(String typeName, IJavaDebugTarget debugTarget) {
			fTypeName= typeName;
			fDebugTarget= debugTarget;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof Key) {
				Key key= (Key) obj;
				return fTypeName != null && fDebugTarget != null && fTypeName.equals(key.fTypeName) && fDebugTarget.equals(key.fDebugTarget);
			}
			return false;
		}

		@Override
		public int hashCode() {
			return fTypeName.hashCode() / 2 + fDebugTarget.hashCode() / 2;
		}
	}

	/**
	 * Stores a compiled expression and evaluation engine used to evaluate the expression.
	 */
	static private class Expression {
		private ICompiledExpression fExpression;
		private IAstEvaluationEngine fEngine;

		Expression(ICompiledExpression expression, IAstEvaluationEngine engine) {
			fExpression = expression;
			fEngine = engine;
		}
		public ICompiledExpression getExpression() {
			return fExpression;
		}
		public IAstEvaluationEngine getEngine() {
			return fEngine;
		}
	}

	/**
	 * Listener use to manage the result of the formatter.
	 * Utilizes the 'standard' pretty printer methods to return the result.
	 */
	static private class EvaluationListener implements IEvaluationListener {

		/**
		 * The selector of <code>java.lang.Object#toString()</code>,
		 * used to evaluate 'toString()' for displaying details of values.
		 */
		private static final String fgToString= "toString"; //$NON-NLS-1$


		/**
		 * The signature of <code>java.lang.Object#toString()</code>,
		 * used to evaluate 'toString()' for displaying details of values.
		 */
		private static final String fgToStringSignature= "()Ljava/lang/String;"; //$NON-NLS-1$

		/**
		 * Signature of a string object
		 */
		private static final String STRING_SIGNATURE = "Ljava/lang/String;"; //$NON-NLS-1$

		private IJavaValue fValue;

		private IValueDetailListener fListener;

		private IJavaThread fThread;

		public EvaluationListener(IJavaValue value, IJavaThread thread, IValueDetailListener listener) {
			fValue= value;
			fThread= thread;
			fListener= listener;
		}

		@Override
		public void evaluationComplete(IEvaluationResult result) {
			if (result.hasErrors()) {
				StringBuilder error= new StringBuilder(DebugUIMessages.JavaDetailFormattersManager_Detail_formatter_error___1);
				DebugException exception= result.getException();
				if (exception != null) {
					Throwable throwable= exception.getStatus().getException();
					error.append("\n\t\t"); //$NON-NLS-1$
					if (throwable instanceof InvocationException) {
						error.append(NLS.bind(DebugUIMessages.JavaDetailFormattersManager_An_exception_occurred___0__3, new String[] {((InvocationException) throwable).exception().referenceType().name()}));
					} else if (throwable instanceof UnsupportedOperationException) {
						error = new StringBuilder();
						error.append(DebugUIMessages.JavaDetailFormattersManager_7);
					} else {
						error.append(exception.getStatus().getMessage());
					}
				} else {
					String[] errors= result.getErrorMessages();
					for (int i= 0, length= errors.length; i < length; i++) {
						error.append("\n\t\t").append(errors[i]); //$NON-NLS-1$
					}
				}
				fListener.detailComputed(fValue, error.toString());
			} else {
				try {
					valueToString(result.getValue());
				} catch (DebugException e) {
					fListener.detailComputed(fValue, e.getStatus().getMessage());
				}
			}
		}

		public void valueToString(final IJavaValue objectValue) throws DebugException {
			String nonEvalResult = null;
			StringBuilder result= null;
			if (objectValue.getSignature() == null) {
				// no need to spawn evaluate for a null fValue
				nonEvalResult = DebugUIMessages.JavaDetailFormattersManager_null;
			} else if (objectValue instanceof IJavaPrimitiveValue) {
				// no need to spawn evaluate for a primitive value
				result = new StringBuilder();
				appendJDIPrimitiveValueString(result, objectValue);
			} else if (fThread == null || !fThread.isSuspended()) {
				// no thread available
				result = new StringBuilder();
				result.append(DebugUIMessages.JavaDetailFormattersManager_no_suspended_threads);
				appendJDIValueString(result, objectValue);
			} else if (objectValue instanceof IJavaObject && STRING_SIGNATURE.equals(objectValue.getSignature())) {
				// no need to spawn evaluate for a java.lang.String
				result = new StringBuilder();
				appendJDIValueString(result, objectValue);
			}
			if (result != null) {
				nonEvalResult = result.toString();
			}
			if (nonEvalResult != null) {
				fListener.detailComputed(fValue, nonEvalResult);
				return;
			}

			IEvaluationRunnable eval = new IEvaluationRunnable() {
				@Override
				public void run(IJavaThread thread, IProgressMonitor monitor) throws DebugException {
					StringBuilder buf= new StringBuilder();
					if (objectValue instanceof IJavaArray) {
						appendArrayDetail(buf, (IJavaArray) objectValue);
					} else if (objectValue instanceof IJavaObject) {
						appendObjectDetail(buf, (IJavaObject) objectValue);
					} else {
						appendJDIValueString(buf, objectValue);
					}
					fListener.detailComputed(fValue, buf.toString());
				}
			};
			fThread.runEvaluation(eval, null, DebugEvent.EVALUATION_IMPLICIT, false);
		}

		/*
		 * Gets all values in array and appends the toString() if it is an array of Objects or the value if primitive.
		 * NB - this method is only called if there is no compiled expression for an array to perform an
		 * Arrays.asList().toString() to minimize toString() calls on remote target (i.e. one call to
		 * List.toString() instead of one call per item in the array).
		 */
		protected void appendArrayDetail(StringBuilder result, IJavaArray arrayValue) throws DebugException {
			result.append('[');
			boolean partial = false;
			IJavaValue[] arrayValues = null;
			int maxLength = getMaxDetailLength();
			int maxEntries = (maxLength / 3) + 1; // guess at char/comma/space per entry
			int length = -1;
			try {
				length = arrayValue.getLength();
				if (maxLength > 0 && length > maxEntries) {
					partial = true;
					IVariable[] variables = arrayValue.getVariables(0, maxEntries);
					arrayValues = new IJavaValue[variables.length];
					for (int i = 0; i < variables.length; i++) {
						arrayValues[i] = (IJavaValue) variables[i].getValue();
					}
				} else {
					arrayValues= arrayValue.getValues();
				}
			} catch (DebugException de) {
				JDIDebugUIPlugin.log(de);
				result.append(de.getStatus().getMessage());
				return;
			}

			for (int i= 0; i < arrayValues.length; i++) {
				IJavaValue value= arrayValues[i];
				if (value instanceof IJavaArray) {
					appendArrayDetail(result, (IJavaArray) value);
				} else if (value instanceof IJavaObject) {
					appendObjectDetail(result, (IJavaObject) value);
				} else {
					appendJDIValueString(result, value);
				}
				if (i < arrayValues.length - 1) {
					result.append(',');
					result.append(' ');
				}
				if (partial && result.length() > maxLength) {
					break;
				}
			}
			if (!partial) {
				result.append(']');
			}
		}

		protected void appendJDIPrimitiveValueString(StringBuilder result, IJavaValue value) throws DebugException {
			result.append(value.getValueString());
		}


		protected void appendJDIValueString(StringBuilder result, IJavaValue value) throws DebugException {
			result.append(value.getValueString());
		}


		protected void appendObjectDetail(StringBuilder result, IJavaObject objectValue) throws DebugException {
			if(objectValue instanceof JDINullValue) {
				appendJDIValueString(result, objectValue);
				return;
			}
			// optimize if the result is a string - no need to send toString to a string
			if (STRING_SIGNATURE.equals(objectValue.getSignature())) {
				appendJDIValueString(result, objectValue);
			} else {

				IJavaValue toStringValue= objectValue.sendMessage(EvaluationListener.fgToString, EvaluationListener.fgToStringSignature, null, fThread, false);
				if (toStringValue == null) {
					result.append(DebugUIMessages.JavaDetailFormattersManager__unknown_);
				} else {
					appendJDIValueString(result, toStringValue);
				}
			}
		}



	}

	/**
	 * (non java-doc)
	 * Remove the provided <code>detailFormatter</code> from the map
	 * @param detailFormatter the detail formatter
	 */
	public void removeAssociatedDetailFormatter(DetailFormatter detailFormatter) {
		fDetailFormattersMap.remove(detailFormatter.getTypeName());
		savePreference();
	}

	/**
	 * Returns the maximum number of chars to display in the details area or 0 if
	 * there is no maximum.
	 *
	 * @return maximum number of chars to display or 0 for no max
	 */
	private static int getMaxDetailLength() {
		return DebugUITools.getPreferenceStore().getInt(IDebugUIConstants.PREF_MAX_DETAIL_LENGTH);
	}

}
