static void Main(string[] args)
        {
            Console.WriteLine("AttributeExtension:");
            Demonstrate_AttributeExtension();
            Console.WriteLine("next up is ObjectExtension" + Environment.NewLine);
            Console.ReadKey();

            Configuration.ObjectExtenderConfig.ConfigureTypeSpecific();
            ObjectExtender.StartExtension();

            var obj = new MarkedObject();

            obj.RegisterAction("write", () => Console.WriteLine("von key aufgerufen"));
            obj.RegisterAction <string, int>("writeNumber", i => Console.WriteLine("mit nummer: " + i));
            obj.Call("write");

            Action _do = () =>
            {
                int index = 0;
                for (int i = 0; i < 1000; i++)
                {
                    obj.Call <string, int>("writeNumber", index);
                    index++;
                }
            };

            _do();

            try
            {
                obj.RegisterFunc <string, int>("funcy", () => 42);
                int i = obj.Invoke <string, int>("FUNKY");
            }
            catch (AttributeNotFoundException e)
            {
                Console.WriteLine(e.Message);
            }
            Console.WriteLine(obj.Invoke <string, int>("funcy"));

            Console.WriteLine("######################################");
            Console.WriteLine("TestPropertyManager:");
            TestPropertyMapper(obj);

            Console.ReadLine();
        }
        /// <summary>
        /// (sloppy coded) integration test
        /// </summary>
        private static void TestPropertyMapper(MarkedObject obj)
        {
            var mapper = obj.GeneratePropertyManager();

            if (mapper.TryGetProperty(nameof(MarkedObject.No), out int val))
            {
                Console.WriteLine(val + " number initially (should be zero)");
                Set(mapper, nameof(MarkedObject.No), 42);
                Console.WriteLine("after it was set: " + obj.No);
            }

            string name = nameof(MarkedObject.IntNo);

            if (mapper.TryGetProperty(name, out val))
            {
                Console.WriteLine(val + " 'Internal' number initially (should be zero)");
                Set(mapper, name, 112);
                Console.WriteLine("after it was set: " + obj.IntNo);
            }

            name = nameof(MarkedObject.IntText);
            if (mapper.TryGetProperty(name, out string s))
            {
                Console.WriteLine(s + " number initially (should be null/empty)");
                Set(mapper, name, "wassettothistext");
                Console.WriteLine("after it was set: " + obj.IntText);
            }

            name = nameof(MarkedObject.StaticText);
            if (mapper.TryGetProperty(name, out s))
            {
                Console.WriteLine(s + " static initially (should be null/empty)");
                Set(mapper, name, "Static was set to this text");
                Console.WriteLine("after it was set: " + MarkedObject.StaticText);
            }
        }
        /**
         * Signals that an <CODE>Element</CODE> was added to the <CODE>Document</CODE>.
         *
         * @return  <CODE>true</CODE> if the element was added, <CODE>false</CODE> if not.
         * @throws  DocumentException when a document isn't open yet, or has been closed
         */

        public override bool Add(IElement element)
        {
            if (pause)
            {
                return(false);
            }
            if (open && !element.IsContent())
            {
                throw new DocumentException("The document is open; you can only add Elements with content.");
            }
            switch (element.Type)
            {
            case Element.HEADER:
                try {
                    Header h = (Header)element;
                    if (HtmlTags.STYLESHEET.Equals(h.Name))
                    {
                        WriteLink(h);
                    }
                    else if (HtmlTags.JAVASCRIPT.Equals(h.Name))
                    {
                        WriteJavaScript(h);
                    }
                    else
                    {
                        WriteHeader(h);
                    }
                }
                catch (InvalidCastException) {
                }
                return(true);

            case Element.SUBJECT:
            case Element.KEYWORDS:
            case Element.AUTHOR:
                Meta meta = (Meta)element;
                WriteHeader(meta);
                return(true);

            case Element.TITLE:
                AddTabs(2);
                WriteStart(HtmlTags.TITLE);
                os.WriteByte(GT);
                AddTabs(3);
                Write(HtmlEncoder.Encode(((Meta)element).Content));
                AddTabs(2);
                WriteEnd(HtmlTags.TITLE);
                return(true);

            case Element.CREATOR:
                WriteComment("Creator: " + HtmlEncoder.Encode(((Meta)element).Content));
                return(true);

            case Element.PRODUCER:
                WriteComment("Producer: " + HtmlEncoder.Encode(((Meta)element).Content));
                return(true);

            case Element.CREATIONDATE:
                WriteComment("Creationdate: " + HtmlEncoder.Encode(((Meta)element).Content));
                return(true);

            case Element.MARKED:
                if (element is MarkedSection)
                {
                    MarkedSection ms = (MarkedSection)element;
                    AddTabs(1);
                    WriteStart(HtmlTags.DIV);
                    WriteMarkupAttributes(ms.MarkupAttributes);
                    os.WriteByte(GT);
                    MarkedObject mo = ((MarkedSection)element).Title;
                    if (mo != null)
                    {
                        markup = mo.MarkupAttributes;
                        mo.Process(this);
                    }
                    ms.Process(this);
                    WriteEnd(HtmlTags.DIV);
                    return(true);
                }
                else
                {
                    MarkedObject mo = (MarkedObject)element;
                    markup = mo.MarkupAttributes;
                    return(mo.Process(this));
                }

            default:
                Write(element, 2);
                return(true);
            }
        }