void DrawTimeLine(DateTime begin, DateTime end, bool isArrow)
        {
            if (isArrow)
            {
                var timeLine = new SimpleArrow();
                timeLine.StartPointX = GetPosition(begin);
                timeLine.StartPointY = TargetCanvas.ActualHeight - BottomMargin;
                timeLine.EndPointX   = GetPosition(end);
                timeLine.EndPointY   = TargetCanvas.ActualHeight - BottomMargin;

                timeLine.StrokeThickness = 3;
                timeLine.Background      = new SolidColorBrush()
                {
                    Color = Colors.Black
                };
                TargetCanvas.Children.Add(timeLine);
            }
            else
            {
                var timeLine = new Line();
                timeLine.X1 = GetPosition(begin);;
                timeLine.Y1 = TargetCanvas.ActualHeight - BottomMargin;
                timeLine.X2 = GetPosition(end);
                timeLine.Y2 = TargetCanvas.ActualHeight - BottomMargin;

                timeLine.StrokeThickness = 3;
                timeLine.Stroke          = new SolidColorBrush()
                {
                    Color = Colors.Black
                };
                TargetCanvas.Children.Add(timeLine);
            }
            DrawTimeMark(begin, end);
        }
        void DrawTimeLine()
        {
            //TargetCanvas. UpdateLayout();
            var timeLine = new SimpleArrow();

            timeLine.StartPointX = LeftMargin;
            timeLine.StartPointY = TargetCanvas.ActualHeight - BottomMargin;
            timeLine.EndPointX   = ViewWidth - RightMargin;
            timeLine.EndPointY   = TargetCanvas.ActualHeight - BottomMargin;

            timeLine.StrokeThickness = 3;
            timeLine.Background      = new SolidColorBrush()
            {
                Color = Colors.Black
            };
            TargetCanvas.Children.Add(timeLine);
            DrawTimeMark();
        }
        public void LambdaCombinatorDemo()
        {
            // Combining with messy type parameterisation
            Func<int, int> f1 = x => x * x;
            Func<int, string> f2 = x =>
            {
                if (x > 5)
                {
                    return "X^2 > 5!";
                }
                else return "X^2 < 5 :O";
            };
            Func<int, string> combination = LambdaCombinator.CombineLambdas<int, int, string>(f1, f2);
            Console.WriteLine(combination(3));
            Console.WriteLine(combination(2));
            Console.WriteLine();

            // Nicer combination
            Console.WriteLine("Now trying it with a type-parameter-free combinator...");
            ISimpleArrow result = LambdaCombinator.Comb(new SimpleArrow<int, int>(f1), new SimpleArrow<int, string>(f2));
            SimpleArrow<int, string> arrowResult = (SimpleArrow<int, string>)result;
            Console.WriteLine(arrowResult.function.Invoke(3));

            // Combining in one line
            SimpleArrow<string, string> another = new SimpleArrow<string, string>(x => x.Length.ToString());
            SimpleArrow<int, string> anotherResult = (SimpleArrow<int, string>)(LambdaCombinator.Comb(
                LambdaCombinator.Comb(
                    new SimpleArrow<int, int>(f1),
                    new SimpleArrow<int, string>(f2)),
                another));
            Console.WriteLine(anotherResult.function.Invoke(3));

            // Combining in one line without downcasting (using only arrow interfaces now)
            ISimpleArrow thingy = LambdaCombinator.Comb(
                new SimpleArrow<int, string>(x => x.ToString()),
                new SimpleArrow<string, int>(x => x.Length)
            );
            Console.WriteLine(thingy.Invoke(1234));
        }