Renderer.materials leaking materials

I recently found out that Materials are not garbage collected in the regular GC pass.
This causes our project to leak materials at a prodigious rate.
So I added some code to pool and reuse materials:

//! add rendering components to a gameobject
public override void AddComponents(SWFCRenderable obj)
{
    base.AddComponents(obj);

    // create mesh filter and mesh renderer
    MeshRenderer render = obj.MeshRender;
    render.enabled = true;
    obj.Filter.mesh = m_mesh;

    // duplicate each of the materials so we can use renderQueue
    Material[] newMats = Dictionary.AllocateMaterials(m_materials.Length);
    for (int i = 0; i < m_materials.Length; i++)
    {
        newMats<em>.CopyPropertiesFromMaterial(m_materials*);*</em>

newMats.shader = m_materials*.shader;
_}
render.materials = newMats;
}
//! remove rendering components from a gameobject*

public override void RemoveComponents(SWFCRenderable obj)
{
Dictionary.FreeMaterials(obj.MeshRender.materials);
base.RemoveComponents(obj);
obj.MeshRender = null;
obj.Filter = null;
}
The problem is that I’m still leaking materials.
My best guess is that setting render.materials does not properly flag the renderer as having local materials… So the next time that renderer.materials is read, it clones the materials in the array over again.
Does anybody have any insight into what’s going on, or how I can get these materials to stop leaking?_

OK here’s what is happening.
The FIRST time you call the getter for material or materials, it CLONES all the materials on the object. It does this even if you supplied the materials in the first place via the setter. For example:

render.material = new Material(Shader.Find(***));   // assign a material
Material mat = render.material; // clones the new material... LEAK!!

This will leak, since the call to the getter causes the renderer to clone the material, even though you supplied it. The following code is better:

Material mat = render.material; // clones the existing material
mat.shader = Shader.Find(***);

The first line clones the material already assigned. The second line alters the cloned material.

This is even more problematic when using a model with multiple materials, since the time when the materials in the renderer become valid does not seem to be properly defined.

MeshFilter mesh = gameObject.GetComponent<MeshFilter>();
MeshRenderer render = gameObject.GetComponent<MeshRenderer>();
mesh.mesh = someMesh;
Material[] mats = render.materials; // clones the materials on the renderer

Note that the last line clones the materials, BUT there are not the correct number of materials in the array for the mesh… The way I got around this was to store an array of materials with my mesh:

MeshFilter mesh = gameObject.GetComponent<MeshFilter>();
MeshRenderer render = gameObject.GetComponent<MeshRenderer>();
mesh.mesh = someMesh;
render.materials = storedMaterials;
Material[] mats = render.materials;   // clones storedMaterials

So I set the renderer to use the stored materials. Then I read from materials getter, which causes them to be cloned (this is what I want since I need to alter them programmatically).

Note that if I clone the materials myself before assigned them to render.materials, then read from render.materials, I lose access to the materials I cloned, causing a leak.

It is important to note that the materials are cloned on the very first read of material/materials ONLY. Subsequent reads will not clone the material. This could turn around and bite you if the very first read is out of your control.