diff --git a/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs b/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs
index 44cd8adf48..b21c31b49e 100644
--- a/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs
+++ b/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs
@@ -74,12 +74,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
uniqueObjectsPreIntern.Add(obj);
ISupportsInterning s = obj as ISupportsInterning;
if (s != null) {
- s.PrepareForInterning(this);
ISupportsInterning output;
- if (supportsInternDict.TryGetValue(s, out output))
+ if (supportsInternDict.TryGetValue(s, out output)) {
obj = (T)output;
- else
- supportsInternDict.Add(s, s);
+ } else {
+ s.PrepareForInterning(this);
+ if (supportsInternDict.TryGetValue(s, out output))
+ obj = (T)output;
+ else
+ supportsInternDict.Add(s, s);
+ }
} else if (obj is string || obj is IType || obj is bool || obj is int) {
object output;
if (byValueDict.TryGetValue(obj, out output))
diff --git a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
index 7e77fa5fb3..3e8f456553 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
@@ -7,6 +7,24 @@ using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
+ ///
+ /// Provider used for interning.
+ ///
+ ///
+ /// A simple IInterningProvider implementation could use 3 dictionaries:
+ /// 1. using value equality comparer (for certain types known to implement value equality, e.g. string and IType)
+ /// 2. using comparer that calls into ISupportsInterning (for types implementing ISupportsInterning)
+ /// 3. list comparer (for InternList method)
+ ///
+ /// On the first Intern()-call, the provider tells the object to prepare for interning (ISupportsInterning.PrepareForInterning)
+ /// and stores it into a dictionary. On further Intern() calls, the original object is returned for all equal objects.
+ /// This allows reducing the memory usage by using a single object instance where possible.
+ ///
+ /// Interning provider implementations could also use the interning logic for different purposes:
+ /// for example, it could be used to determine which objects are used jointly between multiple type definitions
+ /// and which are used only within a single type definition. Then a persistent file format could be organized so
+ /// that shared objects are loaded only once, yet non-shared objects get loaded lazily together with the class.
+ ///
[ContractClass(typeof(IInterningProviderContract))]
public interface IInterningProvider
{
diff --git a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
index 2f3e312110..c937f605b9 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
@@ -9,6 +9,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
///
/// Interface for DOM objects that support interning.
+ /// See for more information.
///
[ContractClass(typeof(ISupportsInterningContract))]
public interface ISupportsInterning