public void Hook(ResourceHookType hookType, IResourceAccess rawAccess)
        {
            Access access = rawAccess as Access;

            if (hookType == ResourceHookType.AfterWrite)
            {
                while (true)
                {
                    bool            netsChanged      = access.netsChanged;
                    List <Node>     dirtyNodes       = access.dirtyNodes;
                    List <Instance> instancesAdded   = access.instancesAdded;
                    List <Instance> instancesRemoved = access.instancesRemoved;
                    if (!netsChanged && dirtyNodes == null && instancesAdded == null && instancesRemoved == null)
                    {
                        break;
                    }
                    access.netsChanged      = false;
                    access.dirtyNodes       = null;
                    access.instancesAdded   = null;
                    access.instancesRemoved = null;

                    if (netsChanged)
                    {
                        this.subnets = Subnet.UpdateNets(key, access, subnets);
                    }
                    if (dirtyNodes != null)
                    {
                        foreach (Node n in dirtyNodes)
                        {
                            engine.AddDirtyNet(n.Subnet);
                        }
                    }
                    if (instancesAdded != null)
                    {
                        InstanceEvent evnt  = new SimulationInstanceEvent(InstanceEvent.Types.InstanceAdded, this);
                        InstanceEvent evnt2 = new SimulationInstanceEvent(InstanceEvent.Types.InstanceDirty, this);
                        InstanceState state = new InstanceState(access, null);
                        foreach (Instance i in instancesAdded)
                        {
                            state.Instance = i;
                            i.HandleEvent(evnt, state);
                            i.HandleEvent(evnt2, state);
                        }
                    }
                    if (instancesRemoved != null)
                    {
                        InstanceEvent evnt  = new SimulationInstanceEvent(InstanceEvent.Types.InstanceRemoved, this);
                        InstanceState state = new InstanceState(access, null);
                        foreach (Instance i in instancesRemoved)
                        {
                            state.Instance = i;
                            i.HandleEvent(evnt, state);
                        }
                    }
                }
            }
            else if (hookType == ResourceHookType.AfterDowngrade)
            {
                OnSimulationModelModified();

                if (DebugAfterUpdates)
                {
                    Console.WriteLine("Simulation model update complete");
                    foreach (Instance i in instances)
                    {
                        Console.WriteLine("  {0} ports {1}", i, ", ".JoinObjectStrings(i.Ports));
                    }
                    foreach (Node u in nodes)
                    {
                        Port p = u as Port;
                        if (p == null || p.Type == PortType.Passive)
                        {
                            Console.WriteLine("  {0} neighbors {1}", u, ", ".JoinObjectStrings(u.Neighbors));
                        }
                    }
                    foreach (Subnet n in subnets)
                    {
                        HashSet <Node> nNodes     = new HashSet <Node>(n.Nodes);
                        List <string>  driverStrs = new List <string>();
                        foreach (Port u in n.Drivers)
                        {
                            driverStrs.Add(string.Format("{0}/{1}", u, u.GetDrivenValue(key)));
                            nNodes.Remove(u);
                        }
                        foreach (Node u in n.Readers)
                        {
                            nNodes.Remove(u);
                        }
                        Console.WriteLine("  {0} val {1} drivers {2} readers {3} nodes {4}", n, n.GetValue(key),
                                          ", ".JoinObjectStrings(driverStrs),
                                          ", ".JoinObjectStrings(n.Readers),
                                          ", ".JoinObjectStrings(nNodes));
                    }
                }
            }
        }