Q:

How to provide email notifications/workflows for clones

We want to set up a system where administrators of clones receive email notification when the item their clone was cloned from is updated. There will be multiple clones created from this item and ideally we'd like to filter notification by language (so administrators of an English clone don't receive notifications when the French version is updated).
Is there a simple way to implement any of this inside a workflow? If so, which even should I try and hook a workflow action to?
Will I need to extend or override a pipeline to do this?
Crossposted to SDN
http://sdn.sitecore.net/forum/ShowPost.aspx?PostID=34533#34533
EDIT: A little more info:
If the clone doesn't overwrite a field from the original item then there is no notification in the client when the original item field is edited. The change is copied straight through - at least in the master database. BUT - the clone still needs to be published to the web database for this change to take effect online. So I'm a bit stuck - my user needs to perform an action (publish clone) but doesn't know it...
I'd really like to be able hook into notification events somehow.

A:

Answering my own question
The code here was provided by various posters on SDN in this thread:
http://sdn.sitecore.net/forum//ShowPost.aspx?PostID=34012
If anyone that contributed to that thread wants to post up an answer then I'll happily give credit - and rep - where it's due.
Firstly:
John West points out that there are a couple of interesting, though private methods:
private static IEnumerable<Item> GetClonesOfVersion(Item source)
{
    Assert.ArgumentNotNull(source, "source");
    return (from clone in GetAllClones(source)
        where clone.SourceUri == source.Uri
        select clone);
}

private static IEnumerable<Item> GetAllClones(Item source)
{
    Assert.ArgumentNotNull(source, "source");
    return (from link in Globals.LinkDatabase.GetReferrers(source)
        select link.GetSourceItem() into clone
        where ((clone != null) && (clone.Source != null)) && (clone.Source.ID == source.ID)
        select clone);
}

There's a support ticket asking for these to be made public, otherwise just copy them into your project.
That needs to be coupled with a custom workflow action, which should be compiled and added to a workflow for a source item. 
This one below, provided by Derek Roberti/Lauren Hightower is to force accept of notifications in clones. To provide email notifications we'd need to reverse the logic - instead of performing an action if a clone has notifications we'd want to ensure an action was performed if the clone had no notifications - i.e. was directly inheriting the edited value from the source item.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Data.Clones;
using Sitecore.Diagnostics;
using Sitecore.SecurityModel;
using Sitecore;
using Sitecore.Links;

namespace WorkFlowCustom
{
public class ForceCloneAccept
{
public void Process(Sitecore.Workflows.Simple.WorkflowPipelineArgs args)
{
Item workFlowItem = args.DataItem;
List itemList = GetItemClones(workFlowItem, true);

foreach (Item cloneItem in itemList)
{
List list = new List(workFlowItem.Database.NotificationProvider.GetNotifications(cloneItem));
foreach (Notification n in list)
{
if ((n != null) && (workFlowItem != null))
{
n.Accept(cloneItem);
}
}
}
}

protected virtual List GetItemClones(Item item, bool processChildren)
{
Assert.ArgumentNotNull(item, "item");
List list = new List();

using (new SecurityDisabler())
{
foreach (ItemLink link in Globals.LinkDatabase.GetReferrers(item))

{
if (!(link.SourceFieldID != FieldIDs.Source))
{
Item sourceItem = link.GetSourceItem();
if (sourceItem != null)
{
list.Add(sourceItem);
}
}
}
}
if (processChildren)
{
foreach (Item item4 in item.Children)
{
list.AddRange(this.GetItemClones(item4, true));
}

}
return list;
}

}
} 

And here's some general reading on custom workflows and invoking actions:
http://sdn.sitecore.net/FAQ/API/Cause%20the%20workflow%20to%20invoke%20an%20action.aspx
Thanks to all that provided input!

