//  Public methods

        static public void InitializeSystem()
        {
            // Create the system controller if needed. The SIPs will
            // get a proxy controller object that will handle operations
            // as syscalls.
            // TODO: Further optimizations may allow writing a more
            // efficient proxy that may use shared memory.

#if SINGULARITY_KERNEL
            KernelController controller = new KernelController();

            if (controller != null)
            {
                LocalControllerObject  = controller;
                SystemControllerObject = LocalControllerObject;
                controller.Initialize();
            }
#else
            LocalController controller = new LocalController();

            if (controller != null)
            {
                LocalControllerObject = controller;

                //  For SIPs we need a proxy object that will handle the calls
                //  to the system controller

                SystemControllerObject = new SystemControllerProxy();

                controller.Initialize();
            }
#endif
            if (SystemControllerObject != null)
            {
                SystemControllerObject.Initialize();
                SystemControllerObject.RegisterController();
                QuerySession.InitializeQuerySystem();
            }
        }
        public virtual void EnumerateActiveSources(QuerySourceDelegate sourceDelegate,
                                                   ActiveSourceEntryDelegate activeEntryDelegate,
                                                   QueryEntryDelegate entryDelegate,
                                                   ushort maxEntrySize,
                                                   ref EnumerationContext context)
        {
            if (maxEntrySize == 0)
            {
                maxEntrySize = DefaultEntrySize;
            }

            //  Create a temporary buffer to store the temporary query information

            QueryBuffer entryBuffer = new QueryBuffer(maxEntrySize);

            if ((entryBuffer == null) || (sourceDelegate == null))
            {
                return;
            }

            //  Prepare to query the controller for the source list. We just pick up an number
            //  that would represent the limit for most common cases as the initial guess.

            int currentSize = 100;

            UIntPtr [] sourceArray = new UIntPtr[currentSize];

            if (sourceArray != null)
            {
                //  Query the controller for the actual source list

                int sourceCount = QuerySourcesList(sourceArray, currentSize);

                //
                //  The array was not large enough, attempt again with the new size

                while (sourceCount > currentSize)
                {
                    sourceArray = new UIntPtr[sourceCount];
                    sourceCount = QuerySourcesList(sourceArray, currentSize);
                }

                //
                //  We sucessfully received an array of entries. We walk them and build the
                //  required information
                //

                for (int i = 0; i < sourceCount; i++)
                {
                    UIntPtr sourceHandle  = sourceArray[i];
                    UIntPtr storageHandle = 0;
                    UIntPtr eventType     = 0;
                    UInt16  count         = 0;
                    string  bufferName    = "";

                    if (GetSourceInformation(sourceHandle,
                                             ref storageHandle,
                                             ref eventType,
                                             ref count,
                                             ref bufferName))
                    {
                        if (storageHandle == 0)
                        {
                            //
                            //  This is an active source. The eventing has no information
                            //  about the storage, it has instead information about the
                            //  types of events handled by this source
                            //

                            EventDescriptor descriptor = QuerySession.GetEventDescriptor(this,
                                                                                         eventType);

                            if (descriptor != null)
                            {
                                //  The source is valid, call the delegate with the appropriate
                                //  arguments filled in
                                // TODO: Also retrieve the control flags status


                                if (!sourceDelegate(sourceHandle,
                                                    storageHandle,
                                                    eventType,
                                                    count,
                                                    bufferName,
                                                    descriptor,
                                                    ref context))
                                {
                                    break;
                                }

                                if (entryDelegate != null)
                                {
                                    //  The caller also provided an entry delegate. We need in that
                                    //  case to also enumerate all entries from the active source

                                    for (int index = 0; index < count; index++)
                                    {
                                        if (!QueryActiveEntry(sourceHandle,
                                                              index,
                                                              ref entryBuffer))
                                        {
                                            break;
                                        }

                                        activeEntryDelegate(sourceHandle,
                                                            index,
                                                            descriptor,
                                                            entryBuffer,
                                                            ref context);
                                    }
                                }
                            }
                        }
                        else
                        {
                            //  This source has an associated storage. Enumerate the entries from
                            //  the storage
                            // TODO: we might also want to filter the sources inside the storage
                            // since multiple sources can share the same storage

                            if (!sourceDelegate(sourceHandle,
                                                storageHandle,
                                                eventType,
                                                count,
                                                bufferName,
                                                null,
                                                ref context))
                            {
                                break;
                            }

                            EventingStorage storage = OpenStorage(storageHandle);

                            if (storage != null)
                            {
                                // Instantiate a query session for the storage and
                                // enumerate the entries passing the provided delegate

                                QuerySession query = new QuerySession();

                                if ((query != null) && (context != null) &&
                                    query.Initialize(storage, false))
                                {
                                    query.EnumerateEntries(entryDelegate, ref context);
                                }
                            }
                        }
                    }
                }
            }
        }