diff --git a/Demo/turtle/about_turtle.txt b/Demo/turtle/about_turtle.txt
new file mode 100644
index 0000000..e4ba217
--- /dev/null
+++ b/Demo/turtle/about_turtle.txt
@@ -0,0 +1,76 @@
+
+========================================================
+    A new turtle module for Python
+========================================================
+
+Turtle graphics is a popular way for introducing programming to
+kids. It was part of the original Logo programming language developed
+by Wally Feurzig and Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
+the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
+the direction it is facing, drawing a line as it moves. Give it the
+command turtle.left(25), and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and
+pictures can easily be drawn.
+
+----- turtle.py
+
+This module is an extended reimplementation of turtle.py from the
+Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+Roughly it has the following features added:
+
+- Better animation of the turtle movements, especially of turning the
+    turtle. So the turtles can more easily be used as a visual feedback
+    instrument by the (beginning) programmer.
+
+- Different turtle shapes, gif-images as turtle shapes, user defined
+    and user controllable turtle shapes, among them compound
+    (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+    makes turtles zu very versatile geometrical objects.
+
+- Fine control over turtle movement and screen updates via delay(),
+    and enhanced tracer() and speed() methods.
+
+- Aliases for the most commonly used commands, like fd for forward etc.,
+    following the early Logo traditions. This reduces the boring work of
+    typing long sequences of commands, which often occur in a natural way
+    when kids try to program fancy pictures on their first encounter with
+    turtle graphcis.
+
+- Turtles now have an undo()-method with configurable undo-buffer.
+
+- Some simple commands/methods for creating event driven programs
+    (mouse-, key-, timer-events). Especially useful for programming games.
+
+- A scrollable Canvas class. The default scrollable Canvas can be
+    extended interactively as needed while playing around with the turtle(s).
+
+- A TurtleScreen class with methods controlling background color or
+    background image, window and canvas size and other properties of the
+    TurtleScreen.
+
+- There is a method, setworldcoordinates(), to install a user defined
+    coordinate-system for the TurtleScreen.
+
+- The implementation uses a 2-vector class named Vec2D, derived from tuple.
+    This class is public, so it can be imported by the application programmer,
+    which makes certain types of computations very natural and compact.
+
+- Appearance of the TurtleScreen and the Turtles at startup/import can be
+    configured by means of a turtle.cfg configuration file.
+    The default configuration mimics the appearance of the old turtle module.
+
+- If configured appropriately the module reads in docstrings from a docstring
+    dictionary in some different language, supplied separately  and replaces
+    the english ones by those read in. There is a utility function
+    write_docstringdict() to write a dictionary with the original (english)
+    docstrings to disc, so it can serve as a template for translations.
diff --git a/Demo/turtle/about_turtledemo.txt b/Demo/turtle/about_turtledemo.txt
new file mode 100644
index 0000000..54c25a5
--- /dev/null
+++ b/Demo/turtle/about_turtledemo.txt
@@ -0,0 +1,13 @@
+
+    --------------------------------------
+        About turtleDemo.py
+    --------------------------------------
+
+    Tiny demo Viewer to view turtle graphics example scripts.
+
+    Quickly and dirtyly assembled by Gregor Lingl.
+    June, 2006
+
+    For more information see: turtleDemo - Help
+
+    Have fun!
diff --git a/Demo/turtle/demohelp.txt b/Demo/turtle/demohelp.txt
new file mode 100644
index 0000000..5683875
--- /dev/null
+++ b/Demo/turtle/demohelp.txt
@@ -0,0 +1,75 @@
+
+
+  ----------------------------------------------
+
+      turtleDemo - Help
+
+  ----------------------------------------------
+
+  This document has two sections:
+
+  (1) How to use the demo viewer
+  (2) How to add your own demos to the demo repository
+
+
+  (1) How to use the demo viewer.
+
+  Select a demoscript from the example menu.
+  The (syntax coloured) source code appears in the left
+  source code window. IT CANNOT BE EDITED, but ONLY VIEWED!
+
+  - Press START button to start the demo.
+  - Stop execution by pressing the STOP button.
+  - Clear screen by pressing the CLEAR button.
+  - Restart by pressing the START button again.
+
+  SPECIAL demos are those which run EVENTDRIVEN.
+  (For example clock.py - or oldTurtleDemo.py which
+  in the end expects a mouse click.):
+
+      Press START button to start the demo.
+
+      - Until the EVENTLOOP is entered everything works
+      as in an ordinary demo script.
+
+      - When the EVENTLOOP is entered, you control the
+      application by using the mouse and/or keys (or it's
+      controlled by some timer events)
+      To stop it you can and must press the STOP button.
+
+      While the EVENTLOOP is running, the examples menu is disabled.
+
+      - Only after having pressed the STOP button, you may
+      restart it or choose another example script.
+
+   * * * * * * * *
+   In some rare situations there may occur interferences/conflicts
+   between events concerning the demo script and those concerning the
+   demo-viewer. (They run in the same process.) Strange behaviour may be
+   the consequence and in the worst case you must close and restart the
+   viewer.
+   * * * * * * * *
+
+
+   (2) How to add your own demos to the demo repository
+
+   - scriptname: must begin with tdemo_ ,
+     so it must have the form tdemo_<your-script-name>.py
+
+   - place: same directory as turtleDemo.py or some
+     subdirectory, the name of which must also begin with
+     tdemo_.....
+
+   - requirements on source code:
+       code must contain a main() function which will
+       be executed by the viewer (see provided example scripts)
+       main() may return a string which will be displayed
+       in the Label below the source code window (when execution
+       has finished.) 
+
+       !! For programs, which are EVENT DRIVEN, main must return
+       !! the string "EVENTLOOP". This informs the viewer, that the
+       !! script is still running and must be stopped by the user!
+
+        
+  
diff --git a/Demo/turtle/tdemo_I_dontlike_tiltdemo.py b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
new file mode 100644
index 0000000..7cae675
--- /dev/null
+++ b/Demo/turtle/tdemo_I_dontlike_tiltdemo.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+     tdemo-I_dont_like_tiltdemo.py
+
+Demostrates
+  (a) use of a tilted ellipse as
+      turtle shape
+  (b) stamping that shape
+
+We can remove it, if you don't like it.
+      Without using reset() ;-)
+ ---------------------------------------
+"""
+from tkinter.turtle import *
+import time
+
+def main():
+    reset()
+    shape("circle")
+    resizemode("user")
+
+    pu(); bk(24*18/6.283); rt(90); pd()
+    tilt(45)
+
+    pu()
+
+    turtlesize(16,10,5)
+    color("red", "violet")
+    for i in range(18):
+        fd(24)
+        lt(20)
+        stamp()
+    color("red", "")
+    for i in range(18):
+        fd(24)
+        lt(20)
+        stamp()
+
+    tilt(-15)
+    turtlesize(3, 1, 4)
+    color("blue", "yellow")
+    for i in range(17):
+        fd(24)
+        lt(20)
+        if i%2 == 0:
+            stamp()
+    time.sleep(1)
+    while undobufferentries():
+        undo()
+    ht()
+    write("OK, OVER!", align="center", font=("Courier", 18, "bold"))
+    return "Done!"
+
+if __name__=="__main__":
+    msg = main()
+    print(msg)
+#    mainloop()
diff --git a/Demo/turtle/tdemo_bytedesign.py b/Demo/turtle/tdemo_bytedesign.py
new file mode 100644
index 0000000..742df06
--- /dev/null
+++ b/Demo/turtle/tdemo_bytedesign.py
@@ -0,0 +1,162 @@
+#!/usr/bin/python
+"""      turtle-example-suite:
+
+        tdemo_bytedesign.py
+
+An example adapted from the example-suite
+of PythonCard's turtle graphcis.
+
+It's based on an article in BYTE magazine
+Problem Solving with Logo: Using Turtle
+Graphics to Redraw a Design
+November 1982, p. 118 - 134
+
+-------------------------------------------
+
+Due to the statement
+
+t.delay(0)
+
+in line 152, which sets the animation delay
+to 0, this animation runs in "line per line"
+mode as fast as possible.
+"""
+
+import math
+from tkinter.turtle import Turtle, mainloop
+from time import clock
+
+# wrapper for any additional drawing routines
+# that need to know about each other
+class Designer(Turtle):
+
+    def design(self, homePos, scale):
+        self.up()
+        for i in range(5):
+            self.forward(64.65 * scale)
+            self.down()
+            self.wheel(self.position(), scale)
+            self.up()
+            self.backward(64.65 * scale)
+            self.right(72)
+        self.up()
+        self.goto(homePos)
+        self.right(36)
+        self.forward(24.5 * scale)
+        self.right(198)
+        self.down()
+        self.centerpiece(46 * scale, 143.4, scale)
+        self.getscreen().tracer(True)
+
+    def wheel(self, initpos, scale):
+        self.right(54)
+        for i in range(4):
+            self.pentpiece(initpos, scale)
+        self.down()
+        self.left(36)
+        for i in range(5):
+            self.tripiece(initpos, scale)
+        self.left(36)
+        for i in range(5):
+            self.down()
+            self.right(72)
+            self.forward(28 * scale)
+            self.up()
+            self.backward(28 * scale)
+        self.left(54)
+        self.getscreen().update()
+
+    def tripiece(self, initpos, scale):
+        oldh = self.heading()
+        self.down()
+        self.backward(2.5 * scale)
+        self.tripolyr(31.5 * scale, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.down()
+        self.backward(2.5 * scale)
+        self.tripolyl(31.5 * scale, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.left(72)
+        self.getscreen().update()
+
+    def pentpiece(self, initpos, scale):
+        oldh = self.heading()
+        self.up()
+        self.forward(29 * scale)
+        self.down()
+        for i in range(5):
+            self.forward(18 * scale)
+            self.right(72)
+        self.pentr(18 * scale, 75, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.forward(29 * scale)
+        self.down()
+        for i in range(5):
+            self.forward(18 * scale)
+            self.right(72)
+        self.pentl(18 * scale, 75, scale)
+        self.up()
+        self.goto(initpos)
+        self.setheading(oldh)
+        self.left(72)
+        self.getscreen().update()
+
+    def pentl(self, side, ang, scale):
+        if side < (2 * scale): return
+        self.forward(side)
+        self.left(ang)
+        self.pentl(side - (.38 * scale), ang, scale)
+
+    def pentr(self, side, ang, scale):
+        if side < (2 * scale): return
+        self.forward(side)
+        self.right(ang)
+        self.pentr(side - (.38 * scale), ang, scale)
+
+    def tripolyr(self, side, scale):
+        if side < (4 * scale): return
+        self.forward(side)
+        self.right(111)
+        self.forward(side / 1.78)
+        self.right(111)
+        self.forward(side / 1.3)
+        self.right(146)
+        self.tripolyr(side * .75, scale)
+
+    def tripolyl(self, side, scale):
+        if side < (4 * scale): return
+        self.forward(side)
+        self.left(111)
+        self.forward(side / 1.78)
+        self.left(111)
+        self.forward(side / 1.3)
+        self.left(146)
+        self.tripolyl(side * .75, scale)
+
+    def centerpiece(self, s, a, scale):
+        self.forward(s); self.left(a)
+        if s < (7.5 * scale):
+            return
+        self.centerpiece(s - (1.2 * scale), a, scale)
+
+def main():
+    t = Designer()
+    t.speed(0)
+    t.hideturtle()
+    t.getscreen().delay(0)
+    t.getscreen().tracer(0)
+    at = clock()
+    t.design(t.position(), 2)
+    et = clock()
+    return "runtime: %.2f sec." % (et-at)
+
+if __name__ == '__main__':
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_chaos.py b/Demo/turtle/tdemo_chaos.py
new file mode 100644
index 0000000..73a0453
--- /dev/null
+++ b/Demo/turtle/tdemo_chaos.py
@@ -0,0 +1,63 @@
+# Datei: chaosplotter.py
+# Autor: Gregor Lingl
+# Datum: 31. 5. 2008
+
+# Ein einfaches Programm zur Demonstration von "chaotischem Verhalten".
+
+from tkinter.turtle import *
+
+def f(x):
+    return 3.9*x*(1-x)
+
+def g(x):
+    return 3.9*(x-x**2)
+
+def h(x):
+    return 3.9*x-3.9*x*x
+
+def coosys():
+    penup()
+    goto(-1,0)
+    pendown()
+    goto(n+1,0)
+    penup()
+    goto(0, -0.1)
+    pendown()
+    goto(-0.1, 1.1)
+
+def plot(fun, start, farbe):
+    x = start
+    pencolor(farbe)
+    penup()
+    goto(0, x)
+    pendown()
+    dot(5)
+    for i in range(n):
+        x=fun(x)
+        goto(i+1,x)
+        dot(5)
+
+def main():
+    global n
+    n = 80
+    ox=-250.0
+    oy=-150.0
+    ex= -2.0*ox / n
+    ey=300.0
+
+    reset()
+    setworldcoordinates(-1.0,-0.1, n+1, 1.1)
+    speed(0)
+    hideturtle()
+    coosys()
+    plot(f, 0.35, "blue")
+    plot(g, 0.35, "green")
+    plot(h, 0.35, "red")
+    for s in range(100):
+        setworldcoordinates(0.5*s,-0.1, n+1, 1.1)
+
+    return "Done!"
+
+if __name__ == "__main__":
+    main()
+    mainloop()
diff --git a/Demo/turtle/tdemo_clock.py b/Demo/turtle/tdemo_clock.py
new file mode 100644
index 0000000..c91d4c5
--- /dev/null
+++ b/Demo/turtle/tdemo_clock.py
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+# -*- coding: cp1252 -*-
+"""       turtle-example-suite:
+
+             tdemo_clock.py
+
+Enhanced clock-program, showing date
+and time
+  ------------------------------------
+   Press STOP to exit the program!
+  ------------------------------------
+"""
+from tkinter.turtle import *
+from datetime import datetime
+
+mode("logo")
+
+def jump(distanz, winkel=0):
+    penup()
+    right(winkel)
+    forward(distanz)
+    left(winkel)
+    pendown()
+
+def hand(laenge, spitze):
+    fd(laenge*1.15)
+    rt(90)
+    fd(spitze/2.0)
+    lt(120)
+    fd(spitze)
+    lt(120)
+    fd(spitze)
+    lt(120)
+    fd(spitze/2.0)
+
+def make_hand_shape(name, laenge, spitze):
+    reset()
+    jump(-laenge*0.15)
+    begin_poly()
+    hand(laenge, spitze)
+    end_poly()
+    hand_form = get_poly()
+    register_shape(name, hand_form)
+
+
+def clockface(radius):
+    reset()
+    pensize(7)
+    for i in range(60):
+        jump(radius)
+        if i % 5 == 0:
+            fd(25)
+            jump(-radius-25)
+        else:
+            dot(3)
+            jump(-radius)
+        rt(6)
+
+def setup():
+    global second_hand, minute_hand, hour_hand, writer
+    mode("logo")
+    make_hand_shape("second_hand", 125, 25)
+    make_hand_shape("minute_hand",  130, 25)
+    make_hand_shape("hour_hand", 90, 25)
+    clockface(160)
+    second_hand = Turtle()
+    second_hand.shape("second_hand")
+    second_hand.color("gray20", "gray80")
+    minute_hand = Turtle()
+    minute_hand.shape("minute_hand")
+    minute_hand.color("blue1", "red1")
+    hour_hand = Turtle()
+    hour_hand.shape("hour_hand")
+    hour_hand.color("blue3", "red3")
+    for hand in second_hand, minute_hand, hour_hand:
+        hand.resizemode("user")
+        hand.shapesize(1, 1, 3)
+        hand.speed(0)
+    ht()
+    writer = Turtle()
+    #writer.mode("logo")
+    writer.ht()
+    writer.pu()
+    writer.bk(85)
+
+
+def wochentag(t):
+    wochentag = ["Monday", "Tuesday", "Wednesday",
+        "Thursday", "Friday", "Saturday", "Sunday"]
+    return wochentag[t.weekday()]
+
+def datum(z):
+    monat = ["Jan.", "Feb.", "Mar.", "Apr.", "May", "June",
+             "July", "Aug.", "Sep.", "Oct.", "Nov.", "Dec."]
+    j = z.year
+    m = monat[z.month - 1]
+    t = z.day
+    return "%s %d %d" % (m, t, j)
+
+def tick():
+    t = datetime.today()
+    sekunde = t.second + t.microsecond*0.000001
+    minute = t.minute + sekunde/60.0
+    stunde = t.hour + minute/60.0
+    tracer(False)
+    writer.clear()
+    writer.home()
+    writer.forward(65)
+    writer.write(wochentag(t),
+                 align="center", font=("Courier", 14, "bold"))
+    writer.back(150)
+    writer.write(datum(t),
+                 align="center", font=("Courier", 14, "bold"))
+    writer.forward(85)
+    tracer(True)
+    second_hand.setheading(6*sekunde)
+    minute_hand.setheading(6*minute)
+    hour_hand.setheading(30*stunde)
+    tracer(True)
+    ontimer(tick, 100)
+
+def main():
+    tracer(False)
+    setup()
+    tracer(True)
+    tick()
+    return "EVENTLOOP"
+
+if __name__ == "__main__":
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_colormixer.py b/Demo/turtle/tdemo_colormixer.py
new file mode 100644
index 0000000..93179b3
--- /dev/null
+++ b/Demo/turtle/tdemo_colormixer.py
@@ -0,0 +1,60 @@
+# colormixer
+
+from tkinter.turtle import Screen, Turtle, mainloop
+import sys
+sys.setrecursionlimit(20000)   # overcomes, for now, an instability of Python 3.0
+
+class ColorTurtle(Turtle):
+
+    def __init__(self, x, y):
+        Turtle.__init__(self)
+        self.shape("turtle")
+        self.resizemode("user")
+        self.shapesize(3,3,5)
+        self.pensize(10)
+        self._color = [0,0,0]
+        self.x = x
+        self._color[x] = y
+        self.color(self._color)
+        self.speed(0)
+        self.left(90)
+        self.pu()
+        self.goto(x,0)
+        self.pd()
+        self.sety(1)
+        self.pu()
+        self.sety(y)
+        self.pencolor("gray25")
+        self.ondrag(self.shift)
+
+    def shift(self, x, y):
+        self.sety(max(0,min(y,1)))
+        self._color[self.x] = self.ycor()
+        self.fillcolor(self._color)
+        setbgcolor()
+
+def setbgcolor():
+    screen.bgcolor(red.ycor(), green.ycor(), blue.ycor())
+
+def main():
+    global screen, red, green, blue
+    screen = Screen()
+    screen.delay(0)
+    screen.setworldcoordinates(-1, -0.3, 3, 1.3)
+
+    red = ColorTurtle(0, .5)
+    green = ColorTurtle(1, .5)
+    blue = ColorTurtle(2, .5)
+    setbgcolor()
+
+    writer = Turtle()
+    writer.ht()
+    writer.pu()
+    writer.goto(1,1.15)
+    writer.write("DRAG!",align="center",font=("Arial",30,("bold","italic")))
+    return "EVENTLOOP"
+
+if __name__ == "__main__":
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_forest.py b/Demo/turtle/tdemo_forest.py
new file mode 100644
index 0000000..b117e3b
--- /dev/null
+++ b/Demo/turtle/tdemo_forest.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python
+"""     turtlegraphics-example-suite:
+
+             tdemo_forest.py
+
+Displays a 'forest' of 3 'breadth-first-trees'
+similar to the one from example tree.
+For further remarks see xtx_tree.py
+
+This example is a 'breadth-first'-rewrite of
+a Logo program written by Erich Neuwirth. See:
+http://homepage.univie.ac.at/erich.neuwirth/
+"""
+from tkinter.turtle import Turtle, colormode, tracer, mainloop
+from random import randrange
+from time import clock
+
+def symRandom(n):
+    return randrange(-n,n+1)
+
+def randomize( branchlist, angledist, sizedist ):
+    return [ (angle+symRandom(angledist),
+              sizefactor*1.01**symRandom(sizedist))
+                     for angle, sizefactor in branchlist ]
+
+def randomfd( t, distance, parts, angledist ):
+    for i in range(parts):
+        t.left(symRandom(angledist))
+        t.forward( (1.0 * distance)/parts )
+
+def tree(tlist, size, level, widthfactor, branchlists, angledist=10, sizedist=5):
+    # benutzt Liste von turtles und Liste von Zweiglisten,
+    # fuer jede turtle eine!
+    if level > 0:
+        lst = []
+        brs = []
+        for t, branchlist in list(zip(tlist,branchlists)):
+            t.pensize( size * widthfactor )
+            t.pencolor( 255 - (180 - 11 * level + symRandom(15)),
+                        180 - 11 * level + symRandom(15),
+                        0 )
+            t.pendown()
+            randomfd(t, size, level, angledist )
+            yield 1
+            for angle, sizefactor in branchlist:
+                t.left(angle)
+                lst.append(t.clone())
+                brs.append(randomize(branchlist, angledist, sizedist))
+                t.right(angle)
+        for x in tree(lst, size*sizefactor, level-1, widthfactor, brs,
+                      angledist, sizedist):
+            yield None
+
+
+def start(t,x,y):
+    colormode(255)
+    t.reset()
+    t.speed(0)
+    t.hideturtle()
+    t.left(90)
+    t.penup()
+    t.setpos(x,y)
+    t.pendown()
+
+def doit1(level, pen):
+    pen.hideturtle()
+    start(pen, 20, -208)
+    t = tree( [pen], 80, level, 0.1, [[ (45,0.69), (0,0.65), (-45,0.71) ]] )
+    return t
+
+def doit2(level, pen):
+    pen.hideturtle()
+    start(pen, -135, -130)
+    t = tree( [pen], 120, level, 0.1, [[ (45,0.69), (-45,0.71) ]] )
+    return t
+
+def doit3(level, pen):
+    pen.hideturtle()
+    start(pen, 190, -90)
+    t = tree( [pen], 100, level, 0.1, [[ (45,0.7), (0,0.72), (-45,0.65) ]] )
+    return t
+
+# Hier 3 Baumgeneratoren:
+def main():
+    p = Turtle()
+    p.ht()
+    tracer(75,0)
+    u = doit1(6, Turtle(undobuffersize=1))
+    s = doit2(7, Turtle(undobuffersize=1))
+    t = doit3(5, Turtle(undobuffersize=1))
+    a = clock()
+    while True:
+        done = 0
+        for b in u,s,t:
+            try:
+                b.__next__()
+            except:
+                done += 1
+        if done == 3:
+            break
+
+    tracer(1,10)
+    b = clock()
+    return "runtime: %.2f sec." % (b-a)
+
+if __name__ == '__main__':
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_fractalcurves.py b/Demo/turtle/tdemo_fractalcurves.py
new file mode 100644
index 0000000..b7c387b
--- /dev/null
+++ b/Demo/turtle/tdemo_fractalcurves.py
@@ -0,0 +1,138 @@
+#!/usr/bin/python
+"""      turtle-example-suite:
+
+        tdemo_fractalCurves.py
+
+This program draws two fractal-curve-designs:
+(1) A hilbert curve (in a box)
+(2) A combination of Koch-curves.
+
+The CurvesTurtle class and the fractal-curve-
+methods are taken from the PythonCard example
+scripts for turtle-graphics.
+"""
+from tkinter.turtle import *
+from time import sleep, clock
+
+class CurvesTurtle(Pen):
+    # example derived from
+    # Turtle Geometry: The Computer as a Medium for Exploring Mathematics
+    # by Harold Abelson and Andrea diSessa
+    # p. 96-98
+    def hilbert(self, size, level, parity):
+        if level == 0:
+            return
+        # rotate and draw first subcurve with opposite parity to big curve
+        self.left(parity * 90)
+        self.hilbert(size, level - 1, -parity)
+        # interface to and draw second subcurve with same parity as big curve
+        self.forward(size)
+        self.right(parity * 90)
+        self.hilbert(size, level - 1, parity)
+        # third subcurve
+        self.forward(size)
+        self.hilbert(size, level - 1, parity)
+        # fourth subcurve
+        self.right(parity * 90)
+        self.forward(size)
+        self.hilbert(size, level - 1, -parity)
+        # a final turn is needed to make the turtle
+        # end up facing outward from the large square
+        self.left(parity * 90)
+
+    # Visual Modeling with Logo: A Structural Approach to Seeing
+    # by James Clayson
+    # Koch curve, after Helge von Koch who introduced this geometric figure in 1904
+    # p. 146
+    def fractalgon(self, n, rad, lev, dir):
+        import math
+
+        # if dir = 1 turn outward
+        # if dir = -1 turn inward
+        edge = 2 * rad * math.sin(math.pi / n)
+        self.pu()
+        self.fd(rad)
+        self.pd()
+        self.rt(180 - (90 * (n - 2) / n))
+        for i in range(n):
+            self.fractal(edge, lev, dir)
+            self.rt(360 / n)
+        self.lt(180 - (90 * (n - 2) / n))
+        self.pu()
+        self.bk(rad)
+        self.pd()
+
+    # p. 146
+    def fractal(self, dist, depth, dir):
+        if depth < 1:
+            self.fd(dist)
+            return
+        self.fractal(dist / 3, depth - 1, dir)
+        self.lt(60 * dir)
+        self.fractal(dist / 3, depth - 1, dir)
+        self.rt(120 * dir)
+        self.fractal(dist / 3, depth - 1, dir)
+        self.lt(60 * dir)
+        self.fractal(dist / 3, depth - 1, dir)
+
+def main():
+    ft = CurvesTurtle()
+
+    ft.reset()
+    ft.speed(0)
+    ft.ht()
+    ft.getscreen().tracer(1,0)
+    ft.pu()
+
+    size = 6
+    ft.setpos(-33*size, -32*size)
+    ft.pd()
+
+    ta=clock()
+    ft.fillcolor("red")
+    ft.begin_fill()
+    ft.fd(size)
+
+    ft.hilbert(size, 6, 1)
+
+    # frame
+    ft.fd(size)
+    for i in range(3):
+        ft.lt(90)
+        ft.fd(size*(64+i%2))
+    ft.pu()
+    for i in range(2):
+        ft.fd(size)
+        ft.rt(90)
+    ft.pd()
+    for i in range(4):
+        ft.fd(size*(66+i%2))
+        ft.rt(90)
+    ft.end_fill()
+    tb=clock()
+    res =  "Hilbert: %.2fsec. " % (tb-ta)
+
+    sleep(3)
+
+    ft.reset()
+    ft.speed(0)
+    ft.ht()
+    ft.getscreen().tracer(1,0)
+
+    ta=clock()
+    ft.color("black", "blue")
+    ft.begin_fill()
+    ft.fractalgon(3, 250, 4, 1)
+    ft.end_fill()
+    ft.begin_fill()
+    ft.color("red")
+    ft.fractalgon(3, 200, 4, -1)
+    ft.end_fill()
+    tb=clock()
+    res +=  "Koch: %.2fsec." % (tb-ta)
+    return res
+
+if __name__  == '__main__':
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_lindenmayer_indian.py b/Demo/turtle/tdemo_lindenmayer_indian.py
new file mode 100644
index 0000000..07dd936
--- /dev/null
+++ b/Demo/turtle/tdemo_lindenmayer_indian.py
@@ -0,0 +1,119 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+        xtx_lindenmayer_indian.py
+
+Each morning women in Tamil Nadu, in southern
+India, place designs, created by using rice
+flour and known as kolam on the thresholds of
+their homes.
+
+These can be described by Lindenmayer systems,
+which can easily be implemented with turtle
+graphics and Python.
+
+Two examples are shown here:
+(1) the snake kolam
+(2) anklets of Krishna
+
+Taken from Marcia Ascher: Mathematics
+Elsewhere, An Exploration of Ideas Across
+Cultures
+
+"""
+################################
+# Mini Lindenmayer tool
+###############################
+
+from tkinter.turtle import *
+
+def replace( seq, replacementRules, n ):
+    for i in range(n):
+        newseq = ""
+        for element in seq:
+            newseq = newseq + replacementRules.get(element,element)
+        seq = newseq
+    return seq
+
+def draw( commands, rules ):
+    for b in commands:
+        try:
+            rules[b]()
+        except TypeError:
+            try:
+                draw(rules[b], rules)
+            except:
+                pass
+
+
+def main():
+    ################################
+    # Example 1: Snake kolam
+    ################################
+
+
+    def r():
+        right(45)
+
+    def l():
+        left(45)
+
+    def f():
+        forward(7.5)
+
+    snake_rules = {"-":r, "+":l, "f":f, "b":"f+f+f--f--f+f+f"}
+    snake_replacementRules = {"b": "b+f+b--f--b+f+b"}
+    snake_start = "b--f--b--f"
+
+    drawing = replace(snake_start, snake_replacementRules, 3)
+
+    reset()
+    speed(3)
+    tracer(1,0)
+    ht()
+    up()
+    backward(195)
+    down()
+    draw(drawing, snake_rules)
+
+    from time import sleep
+    sleep(3)
+
+    ################################
+    # Example 2: Anklets of Krishna
+    ################################
+
+    def A():
+        color("red")
+        circle(10,90)
+
+    def B():
+        from math import sqrt
+        color("black")
+        l = 5/sqrt(2)
+        forward(l)
+        circle(l, 270)
+        forward(l)
+
+    def F():
+        color("green")
+        forward(10)
+
+    krishna_rules = {"a":A, "b":B, "f":F}
+    krishna_replacementRules = {"a" : "afbfa", "b" : "afbfbfbfa" }
+    krishna_start = "fbfbfbfb"
+
+    reset()
+    speed(0)
+    tracer(3,0)
+    ht()
+    left(45)
+    drawing = replace(krishna_start, krishna_replacementRules, 3)
+    draw(drawing, krishna_rules)
+    tracer(1)
+    return "Done!"
+
+if __name__=='__main__':
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_minimal_hanoi.py b/Demo/turtle/tdemo_minimal_hanoi.py
new file mode 100644
index 0000000..97e937f
--- /dev/null
+++ b/Demo/turtle/tdemo_minimal_hanoi.py
@@ -0,0 +1,76 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+         tdemo_minimal_hanoi.py
+
+A minimal 'Towers of Hanoi' animation:
+A tower of 6 discs is transferred from the
+left to the right peg.
+
+An imho quite elegant and concise
+implementation using a tower class, which
+is derived from the built-in type list.
+
+Discs are turtles with shape "square", but
+stretched to rectangles by shapesize()
+ ---------------------------------------
+       To exit press STOP button
+ ---------------------------------------
+"""
+from tkinter.turtle import *
+
+class Disc(Turtle):
+    def __init__(self, n):
+        Turtle.__init__(self, shape="square", visible=False)
+        self.pu()
+        self.shapesize(1.5, n*1.5, 2) # square-->rectangle
+        self.fillcolor(n/6., 0, 1-n/6.)
+        self.st()
+
+class Tower(list):
+    "Hanoi tower, a subclass of built-in type list"
+    def __init__(self, x):
+        "create an empty tower. x is x-position of peg"
+        self.x = x
+    def push(self, d):
+        d.setx(self.x)
+        d.sety(-150+34*len(self))
+        self.append(d)
+    def pop(self):
+        d = list.pop(self)
+        d.sety(150)
+        return d
+
+def hanoi(n, from_, with_, to_):
+    if n > 0:
+        hanoi(n-1, from_, to_, with_)
+        to_.push(from_.pop())
+        hanoi(n-1, with_, from_, to_)
+
+def play():
+    onkey(None,"space")
+    clear()
+    hanoi(6, t1, t2, t3)
+    write("press STOP button to exit",
+          align="center", font=("Courier", 16, "bold"))
+
+def main():
+    global t1, t2, t3
+    ht(); penup(); goto(0, -225)   # writer turtle
+    t1 = Tower(-250)
+    t2 = Tower(0)
+    t3 = Tower(250)
+    # make tower of 6 discs
+    for i in range(6,0,-1):
+        t1.push(Disc(i))
+    # prepare spartanic user interface ;-)
+    write("press spacebar to start game",
+          align="center", font=("Courier", 16, "bold"))
+    onkey(play, "space")
+    listen()
+    return "EVENTLOOP"
+
+if __name__=="__main__":
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_paint.py b/Demo/turtle/tdemo_paint.py
new file mode 100644
index 0000000..97c8756
--- /dev/null
+++ b/Demo/turtle/tdemo_paint.py
@@ -0,0 +1,50 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+            tdemo_paint.py
+
+A simple  eventdriven paint program
+
+- use left mouse button to move turtle
+- middle mouse button to change color
+- right mouse button do turn filling on/off
+ -------------------------------------------
+ Play around by clicking into the canvas
+ using all three mouse buttons.
+ -------------------------------------------
+          To exit press STOP button
+ -------------------------------------------
+"""
+from tkinter.turtle import *
+
+def switchupdown(x=0, y=0):
+    if pen()["pendown"]:
+        end_fill()
+        up()
+    else:
+        down()
+        begin_fill()
+
+def changecolor(x=0, y=0):
+    global colors
+    colors = colors[1:]+colors[:1]
+    color(colors[0])
+
+def main():
+    global colors
+    shape("circle")
+    resizemode("user")
+    shapesize(.5)
+    width(3)
+    colors=["red", "green", "blue", "yellow"]
+    color(colors[0])
+    switchupdown()
+    onscreenclick(goto,1)
+    onscreenclick(changecolor,2)
+    onscreenclick(switchupdown,3)
+    return "EVENTLOOP"
+
+if __name__ == "__main__":
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_peace.py b/Demo/turtle/tdemo_peace.py
new file mode 100644
index 0000000..7f7db14
--- /dev/null
+++ b/Demo/turtle/tdemo_peace.py
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+              tdemo_peace.py
+
+A very simple drawing suitable as a beginner's
+programming example.
+
+Uses only commands, which are also available in
+old turtle.py.
+
+Intentionally no variables are used except for the
+colorloop:
+"""
+
+from tkinter.turtle import *
+
+def main():
+    peacecolors = ("red3",  "orange", "yellow",
+                   "seagreen4", "orchid4",
+                   "royalblue1", "dodgerblue4")
+
+    reset()
+    s = Screen()
+    up()
+    goto(-320,-195)
+    width(70)
+
+    for pcolor in peacecolors:
+        color(pcolor)
+        down()
+        forward(640)
+        up()
+        backward(640)
+        left(90)
+        forward(66)
+        right(90)
+
+    width(25)
+    color("white")
+    goto(0,-170)
+    down()
+
+    circle(170)
+    left(90)
+    forward(340)
+    up()
+    left(180)
+    forward(170)
+    right(45)
+    down()
+    forward(170)
+    up()
+    backward(170)
+    left(90)
+    down()
+    forward(170)
+    up()
+
+    goto(0,300) # vanish if hideturtle() is not available ;-)
+    return "Done!!"
+
+if __name__ == "__main__":
+    main()
+    mainloop()
diff --git a/Demo/turtle/tdemo_penrose.py b/Demo/turtle/tdemo_penrose.py
new file mode 100644
index 0000000..e99a5f5
--- /dev/null
+++ b/Demo/turtle/tdemo_penrose.py
@@ -0,0 +1,181 @@
+#!/usr/bin/python
+"""       xturtle-example-suite:
+
+          xtx_kites_and_darts.py
+
+Constructs two aperiodic penrose-tilings,
+consisting of kites and darts, by the method
+of inflation in six steps.
+
+Starting points are the patterns "sun"
+consisting of five kites and "star"
+consisting of five darts.
+
+For more information see:
+ http://en.wikipedia.org/wiki/Penrose_tiling
+ -------------------------------------------
+"""
+from tkinter.turtle import *
+from math import cos, pi
+from time import clock, sleep
+
+f = (5**0.5-1)/2.0   # (sqrt(5)-1)/2 -- golden ratio
+d = 2 * cos(3*pi/10)
+
+def kite(l):
+    fl = f * l
+    lt(36)
+    fd(l)
+    rt(108)
+    fd(fl)
+    rt(36)
+    fd(fl)
+    rt(108)
+    fd(l)
+    rt(144)
+
+def dart(l):
+    fl = f * l
+    lt(36)
+    fd(l)
+    rt(144)
+    fd(fl)
+    lt(36)
+    fd(fl)
+    rt(144)
+    fd(l)
+    rt(144)
+
+def inflatekite(l, n):
+    if n == 0:
+        px, py = pos()
+        h, x, y = int(heading()), round(px,3), round(py,3)
+        tiledict[(h,x,y)] = True
+        return
+    fl = f * l
+    lt(36)
+    inflatedart(fl, n-1)
+    fd(l)
+    rt(144)
+    inflatekite(fl, n-1)
+    lt(18)
+    fd(l*d)
+    rt(162)
+    inflatekite(fl, n-1)
+    lt(36)
+    fd(l)
+    rt(180)
+    inflatedart(fl, n-1)
+    lt(36)
+
+def inflatedart(l, n):
+    if n == 0:
+        px, py = pos()
+        h, x, y = int(heading()), round(px,3), round(py,3)
+        tiledict[(h,x,y)] = False
+        return
+    fl = f * l
+    inflatekite(fl, n-1)
+    lt(36)
+    fd(l)
+    rt(180)
+    inflatedart(fl, n-1)
+    lt(54)
+    fd(l*d)
+    rt(126)
+    inflatedart(fl, n-1)
+    fd(l)
+    rt(144)
+
+def draw(l, n, th=2):
+    clear()
+    l = l * f**n
+    shapesize(l/100.0, l/100.0, th)
+    for k in tiledict:
+        h, x, y = k
+        setpos(x, y)
+        setheading(h)
+        if tiledict[k]:
+            shape("kite")
+            color("black", (0, 0.75, 0))
+        else:
+            shape("dart")
+            color("black", (0.75, 0, 0))
+        stamp()
+
+def sun(l, n):
+    for i in range(5):
+        inflatekite(l, n)
+        lt(72)
+
+def star(l,n):
+    for i in range(5):
+        inflatedart(l, n)
+        lt(72)
+
+def makeshapes():
+    tracer(0)
+    begin_poly()
+    kite(100)
+    end_poly()
+    register_shape("kite", get_poly())
+    begin_poly()
+    dart(100)
+    end_poly()
+    register_shape("dart", get_poly())
+    tracer(1)
+
+def start():
+    reset()
+    ht()
+    pu()
+    makeshapes()
+    resizemode("user")
+
+def test(l=200, n=4, fun=sun, startpos=(0,0), th=2):
+    global tiledict
+    goto(startpos)
+    setheading(0)
+    tiledict = {}
+    a = clock()
+    tracer(0)
+    fun(l, n)
+    b = clock()
+    draw(l, n, th)
+    tracer(1)
+    c = clock()
+    print("Calculation:   %7.4f s" % (b - a))
+    print("Drawing:  %7.4f s" % (c - b))
+    print("Together: %7.4f s" % (c - a))
+    nk = len([x for x in tiledict if tiledict[x]])
+    nd = len([x for x in tiledict if not tiledict[x]])
+    print("%d kites and %d darts = %d pieces." % (nk, nd, nk+nd))
+
+def demo(fun=sun):
+    start()
+    for i in range(8):
+        a = clock()
+        test(300, i, fun)
+        b = clock()
+        t = b - a
+        if t < 2:
+            sleep(2 - t)
+
+def main():
+    #title("Penrose-tiling with kites and darts.")
+    mode("logo")
+    bgcolor(0.3, 0.3, 0)
+    demo(sun)
+    sleep(2)
+    demo(star)
+    pencolor("black")
+    goto(0,-200)
+    pencolor(0.7,0.7,1)
+    write("Please wait...",
+          align="center", font=('Arial Black', 36, 'bold'))
+    test(600, 8, startpos=(70, 117))
+    return "Done"
+
+if __name__ == "__main__":
+    msg = main()
+    mainloop()
diff --git a/Demo/turtle/tdemo_planet_and_moon.py b/Demo/turtle/tdemo_planet_and_moon.py
new file mode 100644
index 0000000..855b56f
--- /dev/null
+++ b/Demo/turtle/tdemo_planet_and_moon.py
@@ -0,0 +1,113 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+        tdemo_planets_and_moon.py
+
+Gravitational system simulation using the
+approximation method from Feynman-lectures,
+p.9-8, using turtlegraphics.
+
+Example: heavy central body, light planet,
+very light moon!
+Planet has a circular orbit, moon a stable
+orbit around the planet.
+
+You can hold the movement temporarily by pressing
+the left mouse button with mouse over the
+scrollbar of the canvas.
+
+"""
+from tkinter.turtle import Shape, Turtle, mainloop, Vec2D as Vec
+from time import sleep
+
+G = 8
+
+class GravSys(object):
+    def __init__(self):
+        self.planets = []
+        self.t = 0
+        self.dt = 0.01
+    def init(self):
+        for p in self.planets:
+            p.init()
+    def start(self):
+        for i in range(10000):
+            self.t += self.dt
+            for p in self.planets:
+                p.step()
+
+class Star(Turtle):
+    def __init__(self, m, x, v, gravSys, shape):
+        Turtle.__init__(self, shape=shape)
+        self.penup()
+        self.m = m
+        self.setpos(x)
+        self.v = v
+        gravSys.planets.append(self)
+        self.gravSys = gravSys
+        self.resizemode("user")
+        self.pendown()
+    def init(self):
+        dt = self.gravSys.dt
+        self.a = self.acc()
+        self.v = self.v + 0.5*dt*self.a
+    def acc(self):
+        a = Vec(0,0)
+        for planet in self.gravSys.planets:
+            if planet != self:
+                v = planet.pos()-self.pos()
+                a += (G*planet.m/abs(v)**3)*v
+        return a
+    def step(self):
+        dt = self.gravSys.dt
+        self.setpos(self.pos() + dt*self.v)
+        if self.gravSys.planets.index(self) != 0:
+            self.setheading(self.towards(self.gravSys.planets[0]))
+        self.a = self.acc()
+        self.v = self.v + dt*self.a
+
+## create compound yellow/blue turtleshape for planets
+
+def main():
+    s = Turtle()
+    s.reset()
+    s.getscreen().tracer(0,0)
+    s.ht()
+    s.pu()
+    s.fd(6)
+    s.lt(90)
+    s.begin_poly()
+    s.circle(6, 180)
+    s.end_poly()
+    m1 = s.get_poly()
+    s.begin_poly()
+    s.circle(6,180)
+    s.end_poly()
+    m2 = s.get_poly()
+
+    planetshape = Shape("compound")
+    planetshape.addcomponent(m1,"orange")
+    planetshape.addcomponent(m2,"blue")
+    s.getscreen().register_shape("planet", planetshape)
+    s.getscreen().tracer(1,0)
+
+    ## setup gravitational system
+    gs = GravSys()
+    sun = Star(1000000, Vec(0,0), Vec(0,-2.5), gs, "circle")
+    sun.color("yellow")
+    sun.shapesize(1.8)
+    sun.pu()
+    earth = Star(12500, Vec(210,0), Vec(0,195), gs, "planet")
+    earth.pencolor("green")
+    earth.shapesize(0.8)
+    moon = Star(1, Vec(220,0), Vec(0,295), gs, "planet")
+    moon.pencolor("blue")
+    moon.shapesize(0.5)
+    gs.init()
+    gs.start()
+    return "Done!"
+
+if __name__ == '__main__':
+    msg = main()
+    print(msg)
+    #mainloop()
diff --git a/Demo/turtle/tdemo_tree.py b/Demo/turtle/tdemo_tree.py
new file mode 100644
index 0000000..3e7f34f
--- /dev/null
+++ b/Demo/turtle/tdemo_tree.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+"""      turtle-example-suite:
+
+             tdemo_tree.py
+
+Displays a 'breadth-first-tree' - in contrast
+to the classical Logo tree drawing programs,
+which use a depth-first-algorithm.
+
+Uses:
+(1) a tree-generator, where the drawing is
+quasi the side-effect, whereas the generator
+always yields None.
+(2) Turtle-cloning: At each branching point the
+current pen is cloned. So in the end there
+are 1024 turtles.
+"""
+from tkinter.turtle import Turtle, mainloop
+from time import clock
+
+def tree(plist, l, a, f):
+    """ plist is list of pens
+    l is length of branch
+    a is half of the angle between 2 branches
+    f is factor by which branch is shortened
+    from level to level."""
+    if l > 3:
+        lst = []
+        for p in plist:
+            p.forward(l)
+            q = p.clone()
+            p.left(a)
+            q.right(a)
+            lst.append(p)
+            lst.append(q)
+        for x in tree(lst, l*f, a, f):
+            yield None
+
+def maketree():
+    p = Turtle()
+    p.setundobuffer(None)
+    p.hideturtle()
+    p.speed(0)
+    p.getscreen().tracer(30,0)
+    p.left(90)
+    p.penup()
+    p.forward(-210)
+    p.pendown()
+    t = tree([p], 200, 65, 0.6375)
+    for x in t:
+        pass
+    print(len(p.getscreen().turtles()))
+
+def main():
+    a=clock()
+    maketree()
+    b=clock()
+    return "done: %.2f sec." % (b-a)
+
+if __name__ == "__main__":
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_wikipedia.py b/Demo/turtle/tdemo_wikipedia.py
new file mode 100644
index 0000000..f694312
--- /dev/null
+++ b/Demo/turtle/tdemo_wikipedia.py
@@ -0,0 +1,65 @@
+"""      turtle-example-suite:
+
+          tdemo_wikipedia3.py
+
+This example is
+inspired by the Wikipedia article on turtle
+graphics. (See example wikipedia1 for URLs)
+
+First we create (ne-1) (i.e. 35 in this
+example) copies of our first turtle p.
+Then we let them perform their steps in
+parallel.
+
+Followed by a complete undo().
+"""
+from tkinter.turtle import Screen, Turtle, mainloop
+from time import clock, sleep
+
+def mn_eck(p, ne,sz):
+    turtlelist = [p]
+    #create ne-1 additional turtles
+    for i in range(1,ne):
+        q = p.clone()
+        q.rt(360.0/ne)
+        turtlelist.append(q)
+        p = q
+    for i in range(ne):
+        c = abs(ne/2.0-i)/(ne*.7)
+        # let those ne turtles make a step
+        # in parallel:
+        for t in turtlelist:
+            t.rt(360./ne)
+            t.pencolor(1-c,0,c)
+            t.fd(sz)
+
+def main():
+    s = Screen()
+    s.bgcolor("black")
+    p=Turtle()
+    p.speed(0)
+    p.hideturtle()
+    p.pencolor("red")
+    p.pensize(3)
+
+    s.tracer(36,0)
+
+    at = clock()
+    mn_eck(p, 36, 19)
+    et = clock()
+    z1 = et-at
+
+    sleep(1)
+
+    at = clock()
+    while any([t.undobufferentries() for t in s.turtles()]):
+        for t in s.turtles():
+            t.undo()
+    et = clock()
+    return "Laufzeit: %.3f sec" % (z1+et-at)
+
+
+if __name__ == '__main__':
+    msg = main()
+    print(msg)
+    mainloop()
diff --git a/Demo/turtle/tdemo_yinyang.py b/Demo/turtle/tdemo_yinyang.py
new file mode 100644
index 0000000..a47dd71
--- /dev/null
+++ b/Demo/turtle/tdemo_yinyang.py
@@ -0,0 +1,49 @@
+#!/usr/bin/python
+"""       turtle-example-suite:
+
+            tdemo_yinyang.py
+
+Another drawing suitable as a beginner's
+programming example.
+
+The small circles are drawn by the circle
+command.
+
+"""
+
+from tkinter.turtle import *
+
+def yin(radius, color1, color2):
+    width(3)
+    color("black", color1)
+    begin_fill()
+    circle(radius/2., 180)
+    circle(radius, 180)
+    left(180)
+    circle(-radius/2., 180)
+    end_fill()
+    left(90)
+    up()
+    forward(radius*0.35)
+    right(90)
+    down()
+    color(color1, color2)
+    begin_fill()
+    circle(radius*0.15)
+    end_fill()
+    left(90)
+    up()
+    backward(radius*0.35)
+    down()
+    left(90)
+
+def main():
+    reset()
+    yin(200, "black", "white")
+    yin(200, "white", "black")
+    ht()
+    return "Done!"
+
+if __name__ == '__main__':
+    main()
+    mainloop()
diff --git a/Demo/turtle/turtle.cfg b/Demo/turtle/turtle.cfg
new file mode 100644
index 0000000..bd89a74
--- /dev/null
+++ b/Demo/turtle/turtle.cfg
@@ -0,0 +1,10 @@
+width = 800
+height = 600
+canvwidth = 1200
+canvheight = 900
+shape = arrow
+mode = standard
+resizemode = auto
+fillcolor = ""
+title = Python turtle graphics demo.
+
diff --git a/Demo/turtle/turtleDemo.py b/Demo/turtle/turtleDemo.py
new file mode 100644
index 0000000..a454382
--- /dev/null
+++ b/Demo/turtle/turtleDemo.py
@@ -0,0 +1,291 @@
+#!/usr/bin/python
+import sys
+import os
+
+from tkinter import *
+from idlelib.Percolator import Percolator
+from idlelib.ColorDelegator import ColorDelegator
+from idlelib.textView import view_file # TextViewer
+from imp import reload
+
+from tkinter import turtle
+import time
+
+STARTUP = 1
+READY = 2
+RUNNING = 3
+DONE = 4
+EVENTDRIVEN = 5
+
+menufont = ("Arial", 12, NORMAL)
+btnfont = ("Arial", 12, 'bold')
+txtfont = ('Lucida Console', 8, 'normal')
+
+def getExampleEntries():
+    cwd = os.getcwd()
+    #print(cwd, os.listdir(cwd))
+    if "turtleDemo.py" not in os.listdir(cwd):
+        print("Directory of turtleDemo must be current working directory!")
+        print("But in your case this is", cwd)
+        sys.exit()
+    entries1 = [entry for entry in os.listdir(cwd) if
+                     entry.startswith("tdemo_") and
+                     not entry.endswith(".pyc")]
+    entries2 = []
+    for entry in entries1:
+        if entry.endswith(".py"):
+            entries2.append(entry)
+        else:
+            path = os.path.join(cwd,entry)
+            sys.path.append(path)
+            subdir = [entry]
+            scripts = [script for script in os.listdir(path) if
+                            script.startswith("tdemo_") and
+                            script.endswith(".py")]
+            entries2.append(subdir+scripts)
+    return entries2
+
+def showDemoHelp():
+    view_file(demo.root, "Help on turtleDemo", "demohelp.txt")
+
+def showAboutDemo():
+    view_file(demo.root, "About turtleDemo", "about_turtledemo.txt")
+
+def showAboutTurtle():
+    view_file(demo.root, "About the new turtle module.", "about_turtle.txt")
+
+class DemoWindow(object):
+
+    def __init__(self, filename=None):   #, root=None):
+        self.root = root = turtle._root = Tk()
+        root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
+
+        #################
+        self.mBar = Frame(root, relief=RAISED, borderwidth=2)
+        self.mBar.pack(fill=X)
+
+        self.ExamplesBtn = self.makeLoadDemoMenu()
+        self.OptionsBtn = self.makeHelpMenu()
+        self.mBar.tk_menuBar(self.ExamplesBtn, self.OptionsBtn) #, QuitBtn)
+
+        root.title('Python turtle-graphics examples')
+        #################
+        self.left_frame = left_frame = Frame(root)
+        self.text_frame = text_frame = Frame(left_frame)
+        self.vbar = vbar =Scrollbar(text_frame, name='vbar')
+        self.text = text = Text(text_frame,
+                                name='text', padx=5, wrap='none',
+                                width=45)
+        vbar['command'] = text.yview
+        vbar.pack(side=LEFT, fill=Y)
+        #####################
+        self.hbar = hbar =Scrollbar(text_frame, name='hbar', orient=HORIZONTAL)
+        hbar['command'] = text.xview
+        hbar.pack(side=BOTTOM, fill=X)
+        #####################
+        text['yscrollcommand'] = vbar.set
+        text.config(font=txtfont)
+        text.config(xscrollcommand=hbar.set)
+        text.pack(side=LEFT, fill=Y, expand=1)
+        #####################
+        self.output_lbl = Label(left_frame, height= 1,text=" --- ", bg = "#ddf",
+                                font = ("Arial", 16, 'normal'))
+        self.output_lbl.pack(side=BOTTOM, expand=0, fill=X)
+        #####################
+        text_frame.pack(side=LEFT, fill=BOTH, expand=0)
+        left_frame.pack(side=LEFT, fill=BOTH, expand=0)
+        self.graph_frame = g_frame = Frame(root)
+
+        turtle.Screen._root = g_frame
+        turtle.Screen._canvas = turtle.ScrolledCanvas(g_frame, 800, 600, 1000, 800)
+        #xturtle.Screen._canvas.pack(expand=1, fill="both")
+        self.screen = _s_ = turtle.Screen()
+#####
+        turtle.TurtleScreen.__init__(_s_, _s_._canvas)
+#####
+        self.scanvas = _s_._canvas
+        #xturtle.RawTurtle.canvases = [self.scanvas]
+        turtle.RawTurtle.screens = [_s_]
+
+        self.scanvas.pack(side=TOP, fill=BOTH, expand=1)
+
+        self.btn_frame = btn_frame = Frame(g_frame, height=100)
+        self.start_btn = Button(btn_frame, text=" START ", font=btnfont, fg = "white",
+                                disabledforeground = "#fed", command=self.startDemo)
+        self.start_btn.pack(side=LEFT, fill=X, expand=1)
+        self.stop_btn = Button(btn_frame, text=" STOP ",  font=btnfont, fg = "white",
+                                disabledforeground = "#fed", command = self.stopIt)
+        self.stop_btn.pack(side=LEFT, fill=X, expand=1)
+        self.clear_btn = Button(btn_frame, text=" CLEAR ",  font=btnfont, fg = "white",
+                                disabledforeground = "#fed", command = self.clearCanvas)
+        self.clear_btn.pack(side=LEFT, fill=X, expand=1)
+
+        self.btn_frame.pack(side=TOP, fill=BOTH, expand=0)
+        self.graph_frame.pack(side=TOP, fill=BOTH, expand=1)
+
+        Percolator(text).insertfilter(ColorDelegator())
+        self.dirty = False
+        self.exitflag = False
+        if filename:
+            self.loadfile(filename)
+        self.configGUI(NORMAL, DISABLED, DISABLED, DISABLED,
+                       "Choose example from menu", "black")
+        self.state = STARTUP
+
+    def _destroy(self):
+        self.root.destroy()
+        sys.exit()
+
+    def configGUI(self, menu, start, stop, clear, txt="", color="blue"):
+        self.ExamplesBtn.config(state=menu)
+
+        self.start_btn.config(state=start)
+        if start==NORMAL:
+            self.start_btn.config(bg="#d00")
+        else:
+            self.start_btn.config(bg="#fca")
+
+        self.stop_btn.config(state=stop)
+        if stop==NORMAL:
+            self.stop_btn.config(bg="#d00")
+        else:
+            self.stop_btn.config(bg="#fca")
+        self.clear_btn.config(state=clear)
+
+        self.clear_btn.config(state=clear)
+        if clear==NORMAL:
+            self.clear_btn.config(bg="#d00")
+        else:
+            self.clear_btn.config(bg="#fca")
+
+        self.output_lbl.config(text=txt, fg=color)
+
+
+    def makeLoadDemoMenu(self):
+        CmdBtn = Menubutton(self.mBar, text='Examples', underline=0, font=menufont)
+        CmdBtn.pack(side=LEFT, padx="2m")
+        CmdBtn.menu = Menu(CmdBtn)
+
+        for entry in getExampleEntries():
+            def loadexample(x):
+                def emit():
+                    self.loadfile(x)
+                return emit
+            if isinstance(entry,str):
+                CmdBtn.menu.add_command(label=entry[6:-3], underline=0, font=menufont,
+                                        command=loadexample(entry))
+            else:
+                _dir, entries = entry[0], entry[1:]
+                CmdBtn.menu.choices = Menu(CmdBtn.menu)
+                for e in entries:
+                    CmdBtn.menu.choices.add_command(label=e[6:-3], underline=0, font=menufont,
+                              command = loadexample(os.path.join(_dir,e)))
+
+                CmdBtn.menu.add_cascade(label=_dir[6:],
+                                        menu = CmdBtn.menu.choices, font=menufont )
+
+        CmdBtn['menu'] = CmdBtn.menu
+        return CmdBtn
+
+
+    def makeHelpMenu(self):
+        CmdBtn = Menubutton(self.mBar, text='Help', underline=0, font = menufont)
+        CmdBtn.pack(side=LEFT, padx='2m')
+        CmdBtn.menu = Menu(CmdBtn)
+
+        CmdBtn.menu.add_command(label='About turtle.py', font=menufont, command=showAboutTurtle)
+        CmdBtn.menu.add_command(label='turtleDemo - Help', font=menufont, command=showDemoHelp)
+        CmdBtn.menu.add_command(label='About turtleDemo', font=menufont, command=showAboutDemo)
+
+        CmdBtn['menu'] = CmdBtn.menu
+        return CmdBtn
+
+    def refreshCanvas(self):
+        if not self.dirty: return
+        self.screen.clear()
+        #self.screen.mode("standard")
+        self.dirty=False
+
+    def loadfile(self,filename):
+        self.refreshCanvas()
+        if os.path.exists(filename) and not os.path.isdir(filename):
+            # load and display file text
+            f = open(filename,'r')
+            chars = f.read()
+            f.close()
+            self.text.delete("1.0", "end")
+            self.text.insert("1.0",chars)
+            direc, fname = os.path.split(filename)
+            self.root.title(fname[6:-3]+" - a Python turtle graphics example")
+            self.module = __import__(fname[:-3])
+            reload(self.module)
+            self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
+                           "Press start button", "red")
+            self.state = READY
+
+    def startDemo(self):
+        self.refreshCanvas()
+        self.dirty = True
+        turtle.TurtleScreen._RUNNING = True
+        self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED,
+                       "demo running...", "black")
+        self.screen.clear()
+        self.screen.mode("standard")
+        self.state = RUNNING
+
+        try:
+            result = self.module.main()
+            if result == "EVENTLOOP":
+                self.state = EVENTDRIVEN
+            else:
+                self.state = DONE
+        except turtle.Terminator:
+            self.state = DONE
+            result = "stopped!"
+        if self.state == DONE:
+            self.configGUI(NORMAL, NORMAL, DISABLED, NORMAL,
+                           result)
+        elif self.state == EVENTDRIVEN:
+            self.exitflag = True
+            self.configGUI(DISABLED, DISABLED, NORMAL, DISABLED,
+                           "use mouse/keys or STOP", "red")
+
+    def clearCanvas(self):
+        self.refreshCanvas()
+        self.screen._delete("all")
+        self.scanvas.config(cursor="")
+        self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED)
+
+    def stopIt(self):
+        if self.exitflag:
+            self.clearCanvas()
+            self.exitflag = False
+            self.configGUI(NORMAL, NORMAL, DISABLED, DISABLED,
+                           "STOPPED!", "red")
+            turtle.TurtleScreen._RUNNING = False
+            #print "stopIT: exitflag = True"
+        else:
+            turtle.TurtleScreen._RUNNING = False
+            #print "stopIt: exitflag = False"
+
+if __name__ == '__main__':
+    demo = DemoWindow()
+    RUN = True
+    while RUN:
+        try:
+            #print("ENTERING mainloop")
+            demo.root.mainloop()
+        except AttributeError:
+            #print("AttributeError!- WAIT A MOMENT!")
+            time.sleep(0.3)
+            print("GOING ON ..")
+            demo.ckearCanvas()
+        except TypeError:
+            demo.screen._delete("all")
+            #print("CRASH!!!- WAIT A MOMENT!")
+            time.sleep(0.3)
+            #print("GOING ON ..")
+            demo.clearCanvas()
+        except:
+            print("BYE!")
+            RUN = False
diff --git a/Demo/turtle/turtledemo_two_canvases.py b/Demo/turtle/turtledemo_two_canvases.py
new file mode 100644
index 0000000..4fdb59a
--- /dev/null
+++ b/Demo/turtle/turtledemo_two_canvases.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+## DEMONSTRATES USE OF 2 CANVASES, SO CANNOT BE RUN IN DEMOVIEWER!
+"""turtle example: Using TurtleScreen and RawTurtle
+for drawing on two distinct canvases.
+"""
+from tkinter.turtle import TurtleScreen, RawTurtle, TK
+
+root = TK.Tk()
+cv1 = TK.Canvas(root, width=300, height=200, bg="#ddffff")
+cv2 = TK.Canvas(root, width=300, height=200, bg="#ffeeee")
+cv1.pack()
+cv2.pack()
+
+s1 = TurtleScreen(cv1)
+s1.bgcolor(0.85, 0.85, 1)
+s2 = TurtleScreen(cv2)
+s2.bgcolor(1, 0.85, 0.85)
+
+p = RawTurtle(s1)
+q = RawTurtle(s2)
+
+p.color("red", (1, 0.85, 0.85))
+p.width(3)
+q.color("blue", (0.85, 0.85, 1))
+q.width(3)
+
+for t in p,q:
+    t.shape("turtle")
+    t.lt(36)
+
+q.lt(180)
+
+for t in p, q:
+    t.begin_fill()
+for i in range(5):
+    for t in p, q:
+        t.fd(50)
+        t.lt(72)
+for t in p,q:
+    t.end_fill()
+    t.lt(54)
+    t.pu()
+    t.bk(50)
+
+## Want to get some info?
+
+print(s1, s2)
+print(p, q)
+print(s1.turtles())
+print(s2.turtles())
+
+TK.mainloop()
diff --git a/Doc/library/tkinter.turtle.rst b/Doc/library/tkinter.turtle.rst
index d91ac8e..575c2fc 100644
--- a/Doc/library/tkinter.turtle.rst
+++ b/Doc/library/tkinter.turtle.rst
@@ -1,288 +1,1887 @@
-:mod:`tkinter.turtle` --- Turtle graphics for Tk
-================================================
+========================================
+:mod:`turtle` --- Turtle graphics for Tk
+========================================
 
-.. module:: tkinter.turtle
-   :platform: Tk
-   :synopsis: An environment for turtle graphics.
-.. moduleauthor:: Guido van Rossum <guido@python.org>
+Introduction
+============
+
+Turtle graphics is a popular way for introducing programming to kids.  It was
+part of the original Logo programming language developed by Wally Feurzig and
+Seymour Papert in 1966.
+
+Imagine a robotic turtle starting at (0, 0) in the x-y plane.  Give it the
+command ``turtle.forward(15)``, and it moves (on-screen!) 15 pixels in the
+direction it is facing, drawing a line as it moves.  Give it the command
+``turtle.left(25)``, and it rotates in-place 25 degrees clockwise.
+
+By combining together these and similar commands, intricate shapes and pictures
+can easily be drawn.
+
+The :mod:`turtle` module is an extended reimplementation of the same-named
+module from the Python standard distribution up to version Python 2.5.
+
+It tries to keep the merits of the old turtle module and to be (nearly) 100%
+compatible with it.  This means in the first place to enable the learning
+programmer to use all the commands, classes and methods interactively when using
+the module from within IDLE run with the ``-n`` switch.
+
+The turtle module provides turtle graphics primitives, in both object-oriented
+and procedure-oriented ways.  Because it uses :mod:`Tkinter` for the underlying
+graphics, it needs a version of python installed with Tk support.
+
+The object-oriented interface uses essentially two+two classes:
+
+1. The :class:`TurtleScreen` class defines graphics windows as a playground for
+   the drawing turtles.  Its constructor needs a :class:`Tkinter.Canvas` or a
+   :class:`ScrolledCanvas` as argument.  It should be used when :mod:`turtle` is
+   used as part of some application.
+
+   Derived from :class:`TurtleScreen` is the subclass :class:`Screen`.  Screen
+   is implemented as sort of singleton, so there can exist only one instance of
+   Screen at a time.  It should be used when :mod:`turtle` is used as a
+   standalone tool for doing graphics.
+
+   All methods of TurtleScreen/Screen also exist as functions, i.e. as part of
+   the procedure-oriented interface.
+
+2. :class:`RawTurtle` (alias: :class:`RawPen`) defines Turtle objects which draw
+   on a :class:`TurtleScreen`.  Its constructor needs a Canvas, ScrolledCanvas
+   or TurtleScreen as argument, so the RawTurtle objects know where to draw.
+
+   Derived from RawTurtle is the subclass :class:`Turtle` (alias: :class:`Pen`),
+   which draws on "the" :class:`Screen` - instance which is automatically
+   created, if not already present.
+
+   All methods of RawTurtle/Turtle also exist as functions, i.e. part of the
+   procedure-oriented interface.
+
+The procedural interface provides functions which are derived from the methods
+of the classes :class:`Screen` and :class:`Turtle`.  They have the same names as
+the corresponding methods.  A screen object is automativally created whenever a
+function derived from a Screen method is called.  An (unnamed) turtle object is
+automatically created whenever any of the functions derived from a Turtle method
+is called.
+
+To use multiple turtles an a screen one has to use the object-oriented interface.
+
+.. note::
+   In the following documentation the argument list for functions is given.
+   Methods, of course, have the additional first argument *self* which is
+   omitted here.
 
 
-.. sectionauthor:: Moshe Zadka <moshez@zadka.site.co.il>
+Overview over available Turtle and Screen methods
+=================================================
+
+Turtle methods
+--------------
+
+Turtle motion
+   Move and draw
+      | :func:`forward` | :func:`fd`
+      | :func:`backward` | :func:`bk` | :func:`back`
+      | :func:`right` | :func:`rt`
+      | :func:`left` | :func:`lt`
+      | :func:`goto` | :func:`setpos` | :func:`setposition`
+      | :func:`setx`
+      | :func:`sety`
+      | :func:`setheading` | :func:`seth`
+      | :func:`home`
+      | :func:`circle`
+      | :func:`dot`
+      | :func:`stamp`
+      | :func:`clearstamp`
+      | :func:`clearstamps`
+      | :func:`undo`
+      | :func:`speed`
+
+   Tell Turtle's state
+      | :func:`position` | :func:`pos`
+      | :func:`towards`
+      | :func:`xcor`
+      | :func:`ycor`
+      | :func:`heading`
+      | :func:`distance`
+
+   Setting and measurement
+      | :func:`degrees`
+      | :func:`radians`
+
+Pen control
+   Drawing state
+      | :func:`pendown` | :func:`pd` | :func:`down`
+      | :func:`penup` | :func:`pu` | :func:`up`
+      | :func:`pensize` | :func:`width`
+      | :func:`pen`
+      | :func:`isdown`
+
+   Color control
+      | :func:`color`
+      | :func:`pencolor`
+      | :func:`fillcolor`
+
+   Filling
+      | :func:`filling`
+      | :func:`begin_fill`
+      | :func:`end_fill`
+
+   More drawing control
+      | :func:`reset`
+      | :func:`clear`
+      | :func:`write`
+
+Turtle state
+   Visibility
+      | :func:`showturtle` | :func:`st`
+      | :func:`hideturtle` | :func:`ht`
+      | :func:`isvisible`
+
+   Appearance
+      | :func:`shape`
+      | :func:`resizemode`
+      | :func:`shapesize` | :func:`turtlesize`
+      | :func:`settiltangle`
+      | :func:`tiltangle`
+      | :func:`tilt`
+
+Using events
+   | :func:`onclick`
+   | :func:`onrelease`
+   | :func:`ondrag`
+
+Special Turtle methods
+   | :func:`begin_poly`
+   | :func:`end_poly`
+   | :func:`get_poly`
+   | :func:`clone`
+   | :func:`getturtle` | :func:`getpen`
+   | :func:`getscreen`
+   | :func:`setundobuffer`
+   | :func:`undobufferentries`
 
 
-The :mod:`tkinter.turtle` module provides turtle graphics primitives, in both an
-object-oriented and procedure-oriented ways. Because it uses :mod:`tkinter` for
-the underlying graphics, it needs a version of python installed with Tk support.
+Methods of TurtleScreen/Screen
+------------------------------
 
-The procedural interface uses a pen and a canvas which are automagically created
-when any of the functions are called.
+Window control
+   | :func:`bgcolor`
+   | :func:`bgpic`
+   | :func:`clear` | :func:`clearscreen`
+   | :func:`reset` | :func:`resetscreen`
+   | :func:`screensize`
+   | :func:`setworldcoordinates`
 
-The :mod:`tkinter.turtle` module defines the following functions:
+Animation control
+   | :func:`delay`
+   | :func:`tracer`
+   | :func:`update`
+
+Using screen events
+   | :func:`listen`
+   | :func:`onkey`
+   | :func:`onclick` | :func:`onscreenclick`
+   | :func:`ontimer`
+
+Settings and special methods
+   | :func:`mode`
+   | :func:`colormode`
+   | :func:`getcanvas`
+   | :func:`getshapes`
+   | :func:`register_shape` | :func:`addshape`
+   | :func:`turtles`
+   | :func:`window_height`
+   | :func:`window_width`
+
+Methods specific to Screen
+   | :func:`bye`
+   | :func:`exitonclick`
+   | :func:`setup`
+   | :func:`title`
 
 
-.. function:: degrees()
+Methods of RawTurtle/Turtle and corresponding functions
+=======================================================
 
-   Set angle measurement units to degrees.
+Most of the examples in this section refer to a Turtle instance called
+``turtle``.
 
-
-.. function:: radians()
-
-   Set angle measurement units to radians.
-
-
-.. function:: setup(**kwargs)
-
-   Sets the size and position of the main window.  Keywords are:
-
-   * ``width``: either a size in pixels or a fraction of the screen. The default is
-     50% of the screen.
-
-   * ``height``: either a size in pixels or a fraction of the screen. The default
-     is 50% of the screen.
-
-   * ``startx``: starting position in pixels from the left edge of the screen.
-     ``None`` is the default value and  centers the window horizontally on screen.
-
-   * ``starty``: starting position in pixels from the top edge of the screen.
-     ``None`` is the default value and  centers the window vertically on screen.
-
-   Examples::
-
-      # Uses default geometry: 50% x 50% of screen, centered.
-      setup()  
-
-      # Sets window to 200x200 pixels, in upper left of screen
-      setup (width=200, height=200, startx=0, starty=0)
-
-      # Sets window to 75% of screen by 50% of screen, and centers it.
-      setup(width=.75, height=0.5, startx=None, starty=None)
-
-
-.. function:: title(title_str)
-
-   Set the window's title to *title*.
-
-
-.. function:: done()
-
-   Enters the Tk main loop.  The window will continue to  be displayed until the
-   user closes it or the process is killed.
-
-
-.. function:: reset()
-
-   Clear the screen, re-center the pen, and set variables to the default values.
-
-
-.. function:: clear()
-
-   Clear the screen.
-
-
-.. function:: tracer(flag)
-
-   Set tracing on/off (according to whether flag is true or not). Tracing means
-   line are drawn more slowly, with an animation of an arrow along the  line.
-
-
-.. function:: speed(speed)
-
-   Set the speed of the turtle. Valid values for the parameter *speed* are
-   ``'fastest'`` (no delay), ``'fast'``, (delay 5ms), ``'normal'`` (delay 10ms),
-   ``'slow'`` (delay 15ms), and ``'slowest'`` (delay 20ms).
-
-
-.. function:: delay(delay)
-
-   Set the speed of the turtle to *delay*, which is given in ms.
-
+Turtle motion
+-------------
 
 .. function:: forward(distance)
+              fd(distance)
 
-   Go forward *distance* steps.
+   :param distance: a number (integer or float)
+
+   Move the turtle forward by the specified *distance*, in the direction the
+   turtle is headed.
+
+   >>> turtle.position()
+   (0.00, 0.00)
+   >>> turtle.forward(25)
+   >>> turtle.position()
+   (25.00,0.00)
+   >>> turtle.forward(-75)
+   >>> turtle.position()
+   (-50.00,0.00)
 
 
-.. function:: backward(distance)
+.. function:: back(distance)
+              bk(distance)
+              backward(distance)
 
-   Go backward *distance* steps.
+   :param distance: a number
 
+   Move the turtle backward by *distance*, opposite to the direction the
+   turtle is headed.  Do not change the turtle's heading.
 
-.. function:: left(angle)
-
-   Turn left *angle* units. Units are by default degrees, but can be set via the
-   :func:`degrees` and :func:`radians` functions.
+   >>> turtle.position()
+   (0.00, 0.00)
+   >>> turtle.backward(30)
+   >>> turtle.position()
+   (-30.00, 0.00)
 
 
 .. function:: right(angle)
+              rt(angle)
 
-   Turn right *angle* units. Units are by default degrees, but can be set via the
-   :func:`degrees` and :func:`radians` functions.
+   :param angle: a number (integer or float)
+
+   Turn turtle right by *angle* units.  (Units are by default degrees, but
+   can be set via the :func:`degrees` and :func:`radians` functions.)  Angle
+   orientation depends on the turtle mode, see :func:`mode`.
+
+   >>> turtle.heading()
+   22.0
+   >>> turtle.right(45)
+   >>> turtle.heading()
+   337.0
 
 
-.. function:: up()
+.. function:: left(angle)
+              lt(angle)
 
-   Move the pen up --- stop drawing.
+   :param angle: a number (integer or float)
 
+   Turn turtle left by *angle* units.  (Units are by default degrees, but
+   can be set via the :func:`degrees` and :func:`radians` functions.)  Angle
+   orientation depends on the turtle mode, see :func:`mode`.
 
-.. function:: down()
+   >>> turtle.heading()
+   22.0
+   >>> turtle.left(45)
+   >>> turtle.heading()
+   67.0
 
-   Move the pen down --- draw when moving.
+.. function:: goto(x, y=None)
+              setpos(x, y=None)
+              setposition(x, y=None)
 
+    :param x: a number or a pair/vector of numbers
+    :param y: a number or ``None``
 
-.. function:: width(width)
+    If *y* is ``None``, *x* must be a pair of coordinates or a :class:`Vec2D`
+    (e.g. as returned by :func:`pos`).
 
-   Set the line width to *width*.
+    Move turtle to an absolute position.  If the pen is down, draw line.  Do
+    not change the turtle's orientation.
 
-
-.. function:: color(s)
-              color((r, g, b))
-              color(r, g, b)
-
-   Set the pen color.  In the first form, the color is specified as a Tk color
-   specification as a string.  The second form specifies the color as a tuple of
-   the RGB values, each in the range [0..1].  For the third form, the color is
-   specified giving the RGB values as three separate parameters (each in the range
-   [0..1]).
-
-
-.. function:: write(text[, move])
-
-   Write *text* at the current pen position. If *move* is true, the pen is moved to
-   the bottom-right corner of the text. By default, *move* is false.
-
-
-.. function:: fill(flag)
-
-   The complete specifications are rather complex, but the recommended  usage is:
-   call ``fill(1)`` before drawing a path you want to fill, and call ``fill(0)``
-   when you finish to draw the path.
-
-
-.. function:: begin_fill()
-
-   Switch turtle into filling mode;  Must eventually be followed by a corresponding
-   end_fill() call. Otherwise it will be ignored.
-
-
-.. function:: end_fill()
-
-   End filling mode, and fill the shape; equivalent to ``fill(0)``.
-
-
-.. function:: circle(radius[, extent])
-
-   Draw a circle with radius *radius* whose center-point is *radius* units left of
-   the turtle. *extent* determines which part of a circle is drawn: if not given it
-   defaults to a full circle.
-
-   If *extent* is not a full circle, one endpoint of the arc is the current pen
-   position. The arc is drawn in a counter clockwise direction if *radius* is
-   positive, otherwise in a clockwise direction.  In the process, the direction of
-   the turtle is changed by the amount of the *extent*.
-
-
-.. function:: goto(x, y)
-              goto((x, y))
-
-   Go to co-ordinates *x*, *y*.  The co-ordinates may be specified either as two
-   separate arguments or as a 2-tuple.
-
-
-.. function:: towards(x, y)
-
-   Return the angle of the line from the turtle's position to the point *x*, *y*.
-   The co-ordinates may be specified either as two separate arguments, as a
-   2-tuple, or as another pen object.
-
-
-.. function:: heading()
-
-   Return the current orientation of the turtle.
-
-
-.. function:: setheading(angle)
-
-   Set the orientation of the turtle to *angle*.
-
-
-.. function:: position()
-
-   Return the current location of the turtle as an ``(x,y)`` pair.
+    >>> tp = turtle.pos()
+    >>> tp
+    (0.00, 0.00)
+    >>> turtle.setpos(60,30)
+    >>> turtle.pos()
+    (60.00,30.00)
+    >>> turtle.setpos((20,80))
+    >>> turtle.pos()
+    (20.00,80.00)
+    >>> turtle.setpos(tp)
+    >>> turtle.pos()
+    (0.00,0.00)
 
 
 .. function:: setx(x)
 
-   Set the x coordinate of the turtle to *x*.
+   :param x: a number (integer or float)
+
+   Set the turtle's first coordinate to *x*, leave second coordinate
+   unchanged.
+
+   >>> turtle.position()
+   (0.00, 240.00)
+   >>> turtle.setx(10)
+   >>> turtle.position()
+   (10.00, 240.00)
 
 
 .. function:: sety(y)
 
-   Set the y coordinate of the turtle to *y*.
+   :param y: a number (integer or float)
+
+   Set the turtle's first coordinate to *y*, leave second coordinate
+   unchanged.
+
+   >>> turtle.position()
+   (0.00, 40.00)
+   >>> turtle.sety(-10)
+   >>> turtle.position()
+   (0.00, -10.00)
 
 
-.. function:: window_width()
+.. function:: setheading(to_angle)
+              seth(to_angle)
 
-   Return the width of the canvas window.
+   :param to_angle: a number (integer or float)
+
+   Set the orientation of the turtle to *to_angle*.  Here are some common
+   directions in degrees:
+
+   =================== ====================
+    standard mode           logo mode
+   =================== ====================
+      0 - east                0 - north
+     90 - north              90 - east
+    180 - west              180 - south
+    270 - south             270 - west
+   =================== ====================
+
+   >>> turtle.setheading(90)
+   >>> turtle.heading()
+   90
+
+
+.. function:: home()
+
+   Move turtle to the origin -- coordinates (0,0) -- and set its heading to
+   its start-orientation (which depends on the mode, see :func:`mode`).
+
+
+.. function:: circle(radius, extent=None, steps=None)
+
+   :param radius: a number
+   :param extent: a number (or ``None``)
+   :param steps: an integer (or ``None``)
+
+   Draw a circle with given *radius*.  The center is *radius* units left of
+   the turtle; *extent* -- an angle -- determines which part of the circle
+   is drawn.  If *extent* is not given, draw the entire circle.  If *extent*
+   is not a full circle, one endpoint of the arc is the current pen
+   position.  Draw the arc in counterclockwise direction if *radius* is
+   positive, otherwise in clockwise direction.  Finally the direction of the
+   turtle is changed by the amount of *extent*.
+
+   As the circle is approximated by an inscribed regular polygon, *steps*
+   determines the number of steps to use.  If not given, it will be
+   calculated automatically.  May be used to draw regular polygons.
+
+   >>> turtle.circle(50)
+   >>> turtle.circle(120, 180)  # draw a semicircle
+
+
+.. function:: dot(size=None, *color)
+
+   :param size: an integer >= 1 (if given)
+   :param color: a colorstring or a numeric color tuple
+
+   Draw a circular dot with diameter *size*, using *color*.  If *size* is
+   not given, the maximum of pensize+4 and 2*pensize is used.
+
+   >>> turtle.dot()
+   >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+
+
+.. function:: stamp()
+
+   Stamp a copy of the turtle shape onto the canvas at the current turtle
+   position.  Return a stamp_id for that stamp, which can be used to delete
+   it by calling ``clearstamp(stamp_id)``.
+
+   >>> turtle.color("blue")
+   >>> turtle.stamp()
+   13
+   >>> turtle.fd(50)
+
+
+.. function:: clearstamp(stampid)
+
+   :param stampid: an integer, must be return value of previous
+                   :func:`stamp` call
+
+   Delete stamp with given *stampid*.
+
+   >>> turtle.color("blue")
+   >>> astamp = turtle.stamp()
+   >>> turtle.fd(50)
+   >>> turtle.clearstamp(astamp)
+
+
+.. function:: clearstamps(n=None)
+
+   :param n: an integer (or ``None``)
+
+   Delete all or first/last *n* of turtle's stamps.  If *n* is None, delete
+   all stamps, if *n* > 0 delete first *n* stamps, else if *n* < 0 delete
+   last *n* stamps.
+
+   >>> for i in range(8):
+   ...     turtle.stamp(); turtle.fd(30)
+   >>> turtle.clearstamps(2)
+   >>> turtle.clearstamps(-2)
+   >>> turtle.clearstamps()
+
+
+.. function:: undo()
+
+   Undo (repeatedly) the last turtle action(s).  Number of available
+   undo actions is determined by the size of the undobuffer.
+
+   >>> for i in range(4):
+   ...     turtle.fd(50); turtle.lt(80)
+   ...
+   >>> for i in range(8):
+   ...     turtle.undo()
+
+
+.. function:: speed(speed=None)
+
+   :param speed: an integer in the range 0..10 or a speedstring (see below)
+
+   Set the turtle's speed to an integer value in the range 0..10.  If no
+   argument is given, return current speed.
+
+   If input is a number greater than 10 or smaller than 0.5, speed is set
+   to 0.  Speedstrings are mapped to speedvalues as follows:
+
+   * "fastest":  0
+   * "fast":  10
+   * "normal":  6
+   * "slow":  3
+   * "slowest":  1
+
+   Speeds from 1 to 10 enforce increasingly faster animation of line drawing
+   and turtle turning.
+
+   Attention: *speed* = 0 means that *no* animation takes
+   place. forward/back makes turtle jump and likewise left/right make the
+   turtle turn instantly.
+
+   >>> turtle.speed(3)
+
+
+Tell Turtle's state
+-------------------
+
+.. function:: position()
+              pos()
+
+   Return the turtle's current location (x,y) (as a :class:`Vec2D` vector).
+
+   >>> turtle.pos()
+   (0.00, 240.00)
+
+
+.. function:: towards(x, y=None)
+
+   :param x: a number or a pair/vector of numbers or a turtle instance
+   :param y: a number if *x* is a number, else ``None``
+
+   Return the angle between the line from turtle position to position specified
+   by (x,y), the vector or the other turtle.  This depends on the turtle's start
+   orientation which depends on the mode - "standard"/"world" or "logo").
+
+   >>> turtle.pos()
+   (10.00, 10.00)
+   >>> turtle.towards(0,0)
+   225.0
+
+
+.. function:: xcor()
+
+   Return the turtle's x coordinate.
+
+   >>> reset()
+   >>> turtle.left(60)
+   >>> turtle.forward(100)
+   >>> print turtle.xcor()
+   50.0
+
+
+.. function:: ycor()
+
+   Return the turtle's y coordinate.
+
+   >>> reset()
+   >>> turtle.left(60)
+   >>> turtle.forward(100)
+   >>> print turtle.ycor()
+   86.6025403784
+
+
+.. function:: heading()
+
+   Return the turtle's current heading (value depends on the turtle mode, see
+   :func:`mode`).
+
+   >>> turtle.left(67)
+   >>> turtle.heading()
+   67.0
+
+
+.. function:: distance(x, y=None)
+
+   :param x: a number or a pair/vector of numbers or a turtle instance
+   :param y: a number if *x* is a number, else ``None``
+
+   Return the distance from the turtle to (x,y), the given vector, or the given
+   other turtle, in turtle step units.
+
+   >>> turtle.pos()
+   (0.00, 0.00)
+   >>> turtle.distance(30,40)
+   50.0
+   >>> joe = Turtle()
+   >>> joe.forward(77)
+   >>> turtle.distance(joe)
+   77.0
+
+
+Settings for measurement
+------------------------
+
+.. function:: degrees(fullcircle=360.0)
+
+   :param fullcircle: a number
+
+   Set angle measurement units, i.e. set number of "degrees" for a full circle.
+   Default value is 360 degrees.
+
+   >>> turtle.left(90)
+   >>> turtle.heading()
+   90
+   >>> turtle.degrees(400.0)  # angle measurement in gon
+   >>> turtle.heading()
+   100
+
+
+.. function:: radians()
+
+   Set the angle measurement units to radians.  Equivalent to
+   ``degrees(2*math.pi)``.
+
+   >>> turtle.heading()
+   90
+   >>> turtle.radians()
+   >>> turtle.heading()
+   1.5707963267948966
+
+
+Pen control
+-----------
+
+Drawing state
+~~~~~~~~~~~~~
+
+.. function:: pendown()
+              pd()
+              down()
+
+   Pull the pen down -- drawing when moving.
+
+
+.. function:: penup()
+              pu()
+              up()
+
+   Pull the pen up -- no drawing when moving.
+
+
+.. function:: pensize(width=None)
+              width(width=None)
+
+   :param width: a positive number
+
+   Set the line thickness to *width* or return it.  If resizemode is set to
+   "auto" and turtleshape is a polygon, that polygon is drawn with the same line
+   thickness.  If no argument is given, the current pensize is returned.
+
+   >>> turtle.pensize()
+   1
+   >>> turtle.pensize(10)   # from here on lines of width 10 are drawn
+
+
+.. function:: pen(pen=None, **pendict)
+
+   :param pen: a dictionary with some or all of the below listed keys
+   :param pendict: one or more keyword-arguments with the below listed keys as keywords
+
+   Return or set the pen's attributes in a "pen-dictionary" with the following
+   key/value pairs:
+
+   * "shown": True/False
+   * "pendown": True/False
+   * "pencolor": color-string or color-tuple
+   * "fillcolor": color-string or color-tuple
+   * "pensize": positive number
+   * "speed": number in range 0..10
+   * "resizemode": "auto" or "user" or "noresize"
+   * "stretchfactor": (positive number, positive number)
+   * "outline": positive number
+   * "tilt": number
+
+   This dicionary can be used as argument for a subsequent call to :func:`pen`
+   to restore the former pen-state.  Moreover one or more of these attributes
+   can be provided as keyword-arguments.  This can be used to set several pen
+   attributes in one statement.
+
+   >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+   >>> turtle.pen()
+   {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+   'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+   'stretchfactor': (1,1), 'speed': 3}
+   >>> penstate=turtle.pen()
+   >>> turtle.color("yellow","")
+   >>> turtle.penup()
+   >>> turtle.pen()
+   {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+   'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+   'stretchfactor': (1,1), 'speed': 3}
+   >>> p.pen(penstate, fillcolor="green")
+   >>> p.pen()
+   {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+   'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+   'stretchfactor': (1,1), 'speed': 3}
+
+
+.. function:: isdown()
+
+   Return ``True`` if pen is down, ``False`` if it's up.
+
+   >>> turtle.penup()
+   >>> turtle.isdown()
+   False
+   >>> turtle.pendown()
+   >>> turtle.isdown()
+   True
+
+
+Color control
+~~~~~~~~~~~~~
+
+.. function:: pencolor(*args)
+
+   Return or set the pencolor.
+
+   Four input formats are allowed:
+
+   ``pencolor()``
+      Return the current pencolor as color specification string, possibly in
+      hex-number format (see example).  May be used as input to another
+      color/pencolor/fillcolor call.
+
+   ``pencolor(colorstring)``
+      Set pencolor to *colorstring*, which is a Tk color specification string,
+      such as ``"red"``, ``"yellow"``, or ``"#33cc8c"``.
+
+   ``pencolor((r, g, b))``
+      Set pencolor to the RGB color represented by the tuple of *r*, *g*, and
+      *b*.  Each of *r*, *g*, and *b* must be in the range 0..colormode, where
+      colormode is either 1.0 or 255 (see :func:`colormode`).
+
+   ``pencolor(r, g, b)``
+      Set pencolor to the RGB color represented by *r*, *g*, and *b*.  Each of
+      *r*, *g*, and *b* must be in the range 0..colormode.
+
+    If turtleshape is a polygon, the outline of that polygon is drawn with the
+    newly set pencolor.
+
+    >>> turtle.pencolor("brown")
+    >>> tup = (0.2, 0.8, 0.55)
+    >>> turtle.pencolor(tup)
+    >>> turtle.pencolor()
+    "#33cc8c"
+
+
+.. function:: fillcolor(*args)
+
+   Return or set the fillcolor.
+
+   Four input formats are allowed:
+
+   ``fillcolor()``
+      Return the current fillcolor as color specification string, possibly in
+      hex-number format (see example).  May be used as input to another
+      color/pencolor/fillcolor call.
+
+   ``fillcolor(colorstring)``
+      Set fillcolor to *colorstring*, which is a Tk color specification string,
+      such as ``"red"``, ``"yellow"``, or ``"#33cc8c"``.
+
+   ``fillcolor((r, g, b))``
+      Set fillcolor to the RGB color represented by the tuple of *r*, *g*, and
+      *b*.  Each of *r*, *g*, and *b* must be in the range 0..colormode, where
+      colormode is either 1.0 or 255 (see :func:`colormode`).
+
+   ``fillcolor(r, g, b)``
+      Set fillcolor to the RGB color represented by *r*, *g*, and *b*.  Each of
+      *r*, *g*, and *b* must be in the range 0..colormode.
+
+    If turtleshape is a polygon, the interior of that polygon is drawn
+    with the newly set fillcolor.
+
+    >>> turtle.fillcolor("violet")
+    >>> col = turtle.pencolor()
+    >>> turtle.fillcolor(col)
+    >>> turtle.fillcolor(0, .5, 0)
+
+
+.. function:: color(*args)
+
+   Return or set pencolor and fillcolor.
+
+   Several input formats are allowed.  They use 0 to 3 arguments as
+   follows:
+
+   ``color()``
+      Return the current pencolor and the current fillcolor as a pair of color
+      specification strings as returned by :func:`pencolor` and
+      :func:`fillcolor`.
+
+   ``color(colorstring)``, ``color((r,g,b))``, ``color(r,g,b)``
+      Inputs as in :func:`pencolor`, set both, fillcolor and pencolor, to the
+      given value.
+
+   ``color(colorstring1, colorstring2)``, ``color((r1,g1,b1), (r2,g2,b2))``
+      Equivalent to ``pencolor(colorstring1)`` and ``fillcolor(colorstring2)``
+      and analogously if the other input format is used.
+
+    If turtleshape is a polygon, outline and interior of that polygon is drawn
+    with the newly set colors.
+
+    >>> turtle.color("red", "green")
+    >>> turtle.color()
+    ("red", "green")
+    >>> colormode(255)
+    >>> color((40, 80, 120), (160, 200, 240))
+    >>> color()
+    ("#285078", "#a0c8f0")
+
+
+See also: Screen method :func:`colormode`.
+
+
+Filling
+~~~~~~~
+
+.. function:: filling()
+
+   Return fillstate (``True`` if filling, ``False`` else).
+
+   >>> turtle.begin_fill()
+   >>> if turtle.filling():
+   ...    turtle.pensize(5)
+   else:
+   ...    turtle.pensize(3)
+
+
+.. function:: begin_fill()
+
+   To be called just before drawing a shape to be filled.
+
+   >>> turtle.color("black", "red")
+   >>> turtle.begin_fill()
+   >>> turtle.circle(60)
+   >>> turtle.end_fill()
+
+
+.. function:: end_fill()
+
+   Fill the shape drawn after the last call to :func:`begin_fill`.
+
+
+More drawing control
+~~~~~~~~~~~~~~~~~~~~
+
+.. function:: reset()
+
+   Delete the turtle's drawings from the screen, re-center the turtle and set
+   variables to the default values.
+
+   >>> turtle.position()
+   (0.00,-22.00)
+   >>> turtle.heading()
+   100.0
+   >>> turtle.reset()
+   >>> turtle.position()
+   (0.00,0.00)
+   >>> turtle.heading()
+   0.0
+
+
+.. function:: clear()
+
+   Delete the turtle's drawings from the screen.  Do not move turtle.  State and
+   position of the turtle as well as drawings of other turtles are not affected.
+
+
+.. function:: write(arg, move=False, align="left", font=("Arial", 8, "normal"))
+
+   :param arg: object to be written to the TurtleScreen
+   :param move: True/False
+   :param align: one of the strings "left", "center" or right"
+   :param font: a triple (fontname, fontsize, fonttype)
+
+   Write text - the string representation of *arg* - at the current turtle
+   position according to *align* ("left", "center" or right") and with the given
+   font.  If *move* is True, the pen is moved to the bottom-right corner of the
+   text.  By default, *move* is False.
+
+   >>> turtle.write("Home = ", True, align="center")
+   >>> turtle.write((0,0), True)
+
+
+Turtle state
+------------
+
+Visibility
+~~~~~~~~~~
+
+.. function:: showturtle()
+              st()
+
+   Make the turtle visible.
+
+   >>> turtle.hideturtle()
+   >>> turtle.showturtle()
+
+
+.. function:: hideturtle()
+              ht()
+
+   Make the turtle invisible.  It's a good idea to do this while you're in the
+   middle of doing some complex drawing, because hiding the turtle speeds up the
+   drawing observably.
+
+   >>> turtle.hideturtle()
+
+
+.. function:: isvisible()
+
+   Return True if the Turtle is shown, False if it's hidden.
+
+   >>> turtle.hideturtle()
+   >>> print turtle.isvisible():
+   False
+
+
+Appearance
+~~~~~~~~~~
+
+.. function:: shape(name=None)
+
+   :param name: a string which is a valid shapename
+
+   Set turtle shape to shape with given *name* or, if name is not given, return
+   name of current shape.  Shape with *name* must exist in the TurtleScreen's
+   shape dictionary.  Initially there are the following polygon shapes: "arrow",
+   "turtle", "circle", "square", "triangle", "classic".  To learn about how to
+   deal with shapes see Screen method :func:`register_shape`.
+
+   >>> turtle.shape()
+   "arrow"
+   >>> turtle.shape("turtle")
+   >>> turtle.shape()
+   "turtle"
+
+
+.. function:: resizemode(rmode=None)
+
+   :param rmode: one of the strings "auto", "user", "noresize"
+
+   Set resizemode to one of the values: "auto", "user", "noresize".  If *rmode*
+   is not given, return current resizemode.  Different resizemodes have the
+   following effects:
+
+   - "auto": adapts the appearance of the turtle corresponding to the value of pensize.
+   - "user": adapts the appearance of the turtle according to the values of
+     stretchfactor and outlinewidth (outline), which are set by
+     :func:`shapesize`.
+   - "noresize": no adaption of the turtle's appearance takes place.
+
+   resizemode("user") is called by :func:`shapesize` when used with arguments.
+
+   >>> turtle.resizemode("noresize")
+   >>> turtle.resizemode()
+   "noresize"
+
+
+.. function:: shapesize(stretch_wid=None, stretch_len=None, outline=None)
+
+   :param stretch_wid: positive number
+   :param stretch_len: positive number
+   :param outline: positive number
+
+   Return or set the pen's attributes x/y-stretchfactors and/or outline.  Set
+   resizemode to "user".  If and only if resizemode is set to "user", the turtle
+   will be displayed stretched according to its stretchfactors: *stretch_wid* is
+   stretchfactor perpendicular to its orientation, *stretch_len* is
+   stretchfactor in direction of its orientation, *outline* determines the width
+   of the shapes's outline.
+
+   >>> turtle.resizemode("user")
+   >>> turtle.shapesize(5, 5, 12)
+   >>> turtle.shapesize(outline=8)
+
+
+.. function:: tilt(angle)
+
+   :param angle: a number
+
+   Rotate the turtleshape by *angle* from its current tilt-angle, but do *not*
+   change the turtle's heading (direction of movement).
+
+   >>> turtle.shape("circle")
+   >>> turtle.shapesize(5,2)
+   >>> turtle.tilt(30)
+   >>> turtle.fd(50)
+   >>> turtle.tilt(30)
+   >>> turtle.fd(50)
+
+
+.. function:: settiltangle(angle)
+
+   :param angle: a number
+
+   Rotate the turtleshape to point in the direction specified by *angle*,
+   regardless of its current tilt-angle.  *Do not* change the turtle's heading
+   (direction of movement).
+
+   >>> turtle.shape("circle")
+   >>> turtle.shapesize(5,2)
+   >>> turtle.settiltangle(45)
+   >>> stamp()
+   >>> turtle.fd(50)
+   >>> turtle.settiltangle(-45)
+   >>> stamp()
+   >>> turtle.fd(50)
+
+
+.. function:: tiltangle()
+
+   Return the current tilt-angle, i.e. the angle between the orientation of the
+   turtleshape and the heading of the turtle (its direction of movement).
+
+   >>> turtle.shape("circle")
+   >>> turtle.shapesize(5,2)
+   >>> turtle.tilt(45)
+   >>> turtle.tiltangle()
+   45
+
+
+Using events
+------------
+
+.. function:: onclick(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-click events on this turtle.  If *fun* is ``None``,
+   existing bindings are removed.  Example for the anonymous turtle, i.e. the
+   procedural way:
+
+   >>> def turn(x, y):
+   ...     left(180)
+   ...
+   >>> onclick(turn)  # Now clicking into the turtle will turn it.
+   >>> onclick(None)  # event-binding will be removed
+
+
+.. function:: onrelease(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-button-release events on this turtle.  If *fun* is
+   ``None``, existing bindings are removed.
+
+   >>> class MyTurtle(Turtle):
+   ...     def glow(self,x,y):
+   ...         self.fillcolor("red")
+   ...     def unglow(self,x,y):
+   ...         self.fillcolor("")
+   ...
+   >>> turtle = MyTurtle()
+   >>> turtle.onclick(turtle.glow)     # clicking on turtle turns fillcolor red,
+   >>> turtle.onrelease(turtle.unglow) # releasing turns it to transparent.
+
+
+.. function:: ondrag(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-move events on this turtle.  If *fun* is ``None``,
+   existing bindings are removed.
+
+   Remark: Every sequence of mouse-move-events on a turtle is preceded by a
+   mouse-click event on that turtle.
+
+   >>> turtle.ondrag(turtle.goto)
+   # Subsequently, clicking and dragging the Turtle will move it across
+   # the screen thereby producing handdrawings (if pen is down).
+
+
+Special Turtle methods
+----------------------
+
+.. function:: begin_poly()
+
+   Start recording the vertices of a polygon.  Current turtle position is first
+   vertex of polygon.
+
+
+.. function:: end_poly()
+
+   Stop recording the vertices of a polygon.  Current turtle position is last
+   vertex of polygon.  This will be connected with the first vertex.
+
+
+.. function:: get_poly()
+
+   Return the last recorded polygon.
+
+   >>> p = turtle.get_poly()
+   >>> turtle.register_shape("myFavouriteShape", p)
+
+
+.. function:: clone()
+
+   Create and return a clone of the turtle with same position, heading and
+   turtle properties.
+
+   >>> mick = Turtle()
+   >>> joe = mick.clone()
+
+
+.. function:: getturtle()
+
+   Return the Turtle object itself.  Only reasonable use: as a function to
+   return the "anonymous turtle":
+
+   >>> pet = getturtle()
+   >>> pet.fd(50)
+   >>> pet
+   <turtle.Turtle object at 0x01417350>
+   >>> turtles()
+   [<turtle.Turtle object at 0x01417350>]
+
+
+.. function:: getscreen()
+
+   Return the :class:`TurtleScreen` object the turtle is drawing on.
+   TurtleScreen methods can then be called for that object.
+
+   >>> ts = turtle.getscreen()
+   >>> ts
+   <turtle.Screen object at 0x01417710>
+   >>> ts.bgcolor("pink")
+
+
+.. function:: setundobuffer(size)
+
+   :param size: an integer or ``None``
+
+   Set or disable undobuffer.  If *size* is an integer an empty undobuffer of
+   given size is installed.  *size* gives the maximum number of turtle actions
+   that can be undone by the :func:`undo` method/function.  If *size* is
+   ``None``, the undobuffer is disabled.
+
+   >>> turtle.setundobuffer(42)
+
+
+.. function:: undobufferentries()
+
+   Return number of entries in the undobuffer.
+
+   >>> while undobufferentries():
+   ...     undo()
+
+
+.. _compoundshapes:
+
+Excursus about the use of compound shapes
+-----------------------------------------
+
+To use compound turtle shapes, which consist of several polygons of different
+color, you must use the helper class :class:`Shape` explicitly as described
+below:
+
+1. Create an empty Shape object of type "compound".
+2. Add as many components to this object as desired, using the
+   :meth:`addcomponent` method.
+
+   For example:
+
+   >>> s = Shape("compound")
+   >>> poly1 = ((0,0),(10,-5),(0,10),(-10,-5))
+   >>> s.addcomponent(poly1, "red", "blue")
+   >>> poly2 = ((0,0),(10,-5),(-10,-5))
+   >>> s.addcomponent(poly2, "blue", "red")
+
+3. Now add the Shape to the Screen's shapelist and use it:
+
+   >>> register_shape("myshape", s)
+   >>> shape("myshape")
+
+
+.. note::
+
+   The :class:`Shape` class is used internally by the :func:`register_shape`
+   method in different ways.  The application programmer has to deal with the
+   Shape class *only* when using compound shapes like shown above!
+
+
+Methods of TurtleScreen/Screen and corresponding functions
+==========================================================
+
+Most of the examples in this section refer to a TurtleScreen instance called
+``screen``.
+
+
+Window control
+--------------
+
+.. function:: bgcolor(*args)
+
+   :param args: a color string or three numbers in the range 0..colormode or a
+                3-tuple of such numbers
+
+   Set or return background color of the TurtleScreen.
+
+   >>> screen.bgcolor("orange")
+   >>> screen.bgcolor()
+   "orange"
+   >>> screen.bgcolor(0.5,0,0.5)
+   >>> screen.bgcolor()
+   "#800080"
+
+
+.. function:: bgpic(picname=None)
+
+   :param picname: a string, name of a gif-file or ``"nopic"``, or ``None``
+
+   Set background image or return name of current backgroundimage.  If *picname*
+   is a filename, set the corresponding image as background.  If *picname* is
+   ``"nopic"``, delete background image, if present.  If *picname* is ``None``,
+   return the filename of the current backgroundimage.
+
+   >>> screen.bgpic()
+   "nopic"
+   >>> screen.bgpic("landscape.gif")
+   >>> screen.bgpic()
+   "landscape.gif"
+
+
+.. function:: clear()
+              clearscreen()
+
+   Delete all drawings and all turtles from the TurtleScreen.  Reset the now
+   empty TurtleScreen to its initial state: white background, no background
+   image, no event bindings and tracing on.
+
+   .. note::
+      This TurtleScreen method is available as a global function only under the
+      name ``clearscreen``.  The global function ``clear`` is another one
+      derived from the Turtle method ``clear``.
+
+
+.. function:: reset()
+              resetscreen()
+
+   Reset all Turtles on the Screen to their initial state.
+
+   .. note::
+      This TurtleScreen method is available as a global function only under the
+      name ``resetscreen``.  The global function ``reset`` is another one
+      derived from the Turtle method ``reset``.
+
+
+.. function:: screensize(canvwidth=None, canvheight=None, bg=None)
+
+   :param canvwidth: positive integer, new width of canvas in pixels
+   :param canvheight: positive integer, new height of canvas in pixels
+   :param bg: colorstring or color-tupel, new background color
+
+   If no arguments are given, return current (canvaswidth, canvasheight).  Else
+   resize the canvas the turtles are drawing on.  Do not alter the drawing
+   window.  To observe hidden parts of the canvas, use the scrollbars. With this
+   method, one can make visible those parts of a drawing which were outside the
+   canvas before.
+
+      >>> turtle.screensize(2000,1500)
+      # e.g. to search for an erroneously escaped turtle ;-)
+
+
+.. function:: setworldcoordinates(llx, lly, urx, ury)
+
+   :param llx: a number, x-coordinate of lower left corner of canvas
+   :param lly: a number, y-coordinate of lower left corner of canvas
+   :param urx: a number, x-coordinate of upper right corner of canvas
+   :param ury: a number, y-coordinate of upper right corner of canvas
+
+   Set up user-defined coordinate system and switch to mode "world" if
+   necessary.  This performs a ``screen.reset()``.  If mode "world" is already
+   active, all drawings are redrawn according to the new coordinates.
+
+   **ATTENTION**: in user-defined coordinate systems angles may appear
+   distorted.
+
+   >>> screen.reset()
+   >>> screen.setworldcoordinates(-50,-7.5,50,7.5)
+   >>> for _ in range(72):
+   ...     left(10)
+   ...
+   >>> for _ in range(8):
+   ...     left(45); fd(2)   # a regular octogon
+
+
+Animation control
+-----------------
+
+.. function:: delay(delay=None)
+
+   :param delay: positive integer
+
+   Set or return the drawing *delay* in milliseconds.  (This is approximately
+   the time interval between two consecutived canvas updates.)  The longer the
+   drawing delay, the slower the animation.
+
+   Optional argument:
+
+   >>> screen.delay(15)
+   >>> screen.delay()
+   15
+
+
+.. function:: tracer(n=None, delay=None)
+
+   :param n: nonnegative integer
+   :param delay: nonnegative integer
+
+   Turn turtle animation on/off and set delay for update drawings.  If *n* is
+   given, only each n-th regular screen update is really performed.  (Can be
+   used to accelerate the drawing of complex graphics.)  Second argument sets
+   delay value (see :func:`delay`).
+
+   >>> screen.tracer(8, 25)
+   >>> dist = 2
+   >>> for i in range(200):
+   ...     fd(dist)
+   ...     rt(90)
+   ...     dist += 2
+
+
+.. function:: update()
+
+   Perform a TurtleScreen update. To be used when tracer is turned off.
+
+See also the RawTurtle/Turtle method :func:`speed`.
+
+
+Using screen events
+-------------------
+
+.. function:: listen(xdummy=None, ydummy=None)
+
+   Set focus on TurtleScreen (in order to collect key-events).  Dummy arguments
+   are provided in order to be able to pass :func:`listen` to the onclick method.
+
+
+.. function:: onkey(fun, key)
+
+   :param fun: a function with no arguments or ``None``
+   :param key: a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+   Bind *fun* to key-release event of key.  If *fun* is ``None``, event bindings
+   are removed. Remark: in order to be able to register key-events, TurtleScreen
+   must have the focus. (See method :func:`listen`.)
+
+   >>> def f():
+   ...     fd(50)
+   ...     lt(60)
+   ...
+   >>> screen.onkey(f, "Up")
+   >>> screen.listen()
+
+
+.. function:: onclick(fun, btn=1, add=None)
+              onscreenclick(fun, btn=1, add=None)
+
+   :param fun: a function with two arguments which will be called with the
+               coordinates of the clicked point on the canvas
+   :param num: number of the mouse-button, defaults to 1 (left mouse button)
+   :param add: ``True`` or ``False`` -- if ``True``, a new binding will be
+               added, otherwise it will replace a former binding
+
+   Bind *fun* to mouse-click events on this screen.  If *fun* is ``None``,
+   existing bindings are removed.
+
+   Example for a TurtleScreen instance named ``screen`` and a Turtle instance
+   named turtle:
+
+   >>> screen.onclick(turtle.goto)
+   # Subsequently clicking into the TurtleScreen will
+   # make the turtle move to the clicked point.
+   >>> screen.onclick(None)  # remove event binding again
+
+   .. note::
+      This TurtleScreen method is available as a global function only under the
+      name ``onscreenclick``.  The global function ``onclick`` is another one
+      derived from the Turtle method ``onclick``.
+
+
+.. function:: ontimer(fun, t=0)
+
+   :param fun: a function with no arguments
+   :param t: a number >= 0
+
+   Install a timer that calls *fun* after *t* milliseconds.
+
+   >>> running = True
+   >>> def f():
+           if running:
+               fd(50)
+               lt(60)
+               screen.ontimer(f, 250)
+   >>> f()   ### makes the turtle marching around
+   >>> running = False
+
+
+Settings and special methods
+----------------------------
+
+.. function:: mode(mode=None)
+
+   :param mode: one of the strings "standard", "logo" or "world"
+
+   Set turtle mode ("standard", "logo" or "world") and perform reset.  If mode
+   is not given, current mode is returned.
+
+   Mode "standard" is compatible with old :mod:`turtle`.  Mode "logo" is
+   compatible with most Logo turtle graphics.  Mode "world" uses user-defined
+   "world coordinates". **Attention**: in this mode angles appear distorted if
+   ``x/y`` unit-ratio doesn't equal 1.
+
+   ============ ========================= ===================
+       Mode      Initial turtle heading     positive angles
+   ============ ========================= ===================
+    "standard"    to the right (east)       counterclockwise
+      "logo"        upward    (north)         clockwise
+   ============ ========================= ===================
+
+   >>> mode("logo")   # resets turtle heading to north
+   >>> mode()
+   "logo"
+
+
+.. function:: colormode(cmode=None)
+
+   :param cmode: one of the values 1.0 or 255
+
+   Return the colormode or set it to 1.0 or 255.  Subsequently *r*, *g*, *b*
+   values of color triples have to be in the range 0..\ *cmode*.
+
+   >>> screen.colormode()
+   1.0
+   >>> screen.colormode(255)
+   >>> turtle.pencolor(240,160,80)
+
+
+.. function:: getcanvas()
+
+   Return the Canvas of this TurtleScreen.  Useful for insiders who know what to
+   do with a Tkinter Canvas.
+
+   >>> cv = screen.getcanvas()
+   >>> cv
+   <turtle.ScrolledCanvas instance at 0x010742D8>
+
+
+.. function:: getshapes()
+
+   Return a list of names of all currently available turtle shapes.
+
+   >>> screen.getshapes()
+   ["arrow", "blank", "circle", ..., "turtle"]
+
+
+.. function:: register_shape(name, shape=None)
+              addshape(name, shape=None)
+
+   There are three different ways to call this function:
+
+   (1) *name* is the name of a gif-file and *shape* is ``None``: Install the
+       corresponding image shape.
+
+       .. note::
+          Image shapes *do not* rotate when turning the turtle, so they do not
+          display the heading of the turtle!
+
+   (2) *name* is an arbitrary string and *shape* is a tuple of pairs of
+       coordinates: Install the corresponding polygon shape.
+
+   (3) *name* is an arbitrary string and shape is a (compound) :class:`Shape`
+       object: Install the corresponding compound shape.
+
+   Add a turtle shape to TurtleScreen's shapelist.  Only thusly registered
+   shapes can be used by issuing the command ``shape(shapename)``.
+
+   >>> screen.register_shape("turtle.gif")
+   >>> screen.register_shape("triangle", ((5,-3), (0,5), (-5,-3)))
+
+
+.. function:: turtles()
+
+   Return the list of turtles on the screen.
+
+   >>> for turtle in screen.turtles()
+   ...     turtle.color("red")
 
 
 .. function:: window_height()
 
-   Return the height of the canvas window.
+   Return the height of the turtle window.
+
+   >>> screen.window_height()
+   480
 
 
-This module also does ``from math import *``, so see the documentation for the
-:mod:`math` module for additional constants and functions useful for turtle
-graphics.
+.. function:: window_width()
+
+   Return the width of the turtle window.
+
+   >>> screen.window_width()
+   640
 
 
-.. function:: demo()
+.. _screenspecific:
 
-   Exercise the module a bit.
+Methods specific to Screen, not inherited from TurtleScreen
+-----------------------------------------------------------
+
+.. function:: bye()
+
+   Shut the turtlegraphics window.
 
 
-.. exception:: Error
+.. function:: exitonclick()
 
-   Exception raised on any error caught by this module.
-
-For examples, see the code of the :func:`demo` function.
-
-This module defines the following classes:
+   Bind bye() method to mouse clicks on the Screen.
 
 
-.. class:: Pen()
+   If the value "using_IDLE" in the configuration dictionary is ``False``
+   (default value), also enter mainloop.  Remark: If IDLE with the ``-n`` switch
+   (no subprocess) is used, this value should be set to ``True`` in
+   :file:`turtle.cfg`.  In this case IDLE's own mainloop is active also for the
+   client script.
 
-   Define a pen. All above functions can be called as a methods on the given pen.
-   The constructor automatically creates a canvas do be drawn on.
+
+.. function:: setup(width=_CFG["width"], height=_CFG["height"], startx=_CFG["leftright"], starty=_CFG["topbottom"])
+
+   Set the size and position of the main window.  Default values of arguments
+   are stored in the configuration dicionary and can be changed via a
+   :file:`turtle.cfg` file.
+
+   :param width: if an integer, a size in pixels, if a float, a fraction of the
+                 screen; default is 50% of screen
+   :param height: if an integer, the height in pixels, if a float, a fraction of
+                  the screen; default is 75% of screen
+   :param startx: if positive, starting position in pixels from the left
+                  edge of the screen, if negative from the right edge, if None,
+                  center window horizontally
+   :param startx: if positive, starting position in pixels from the top
+                  edge of the screen, if negative from the bottom edge, if None,
+                  center window vertically
+
+   >>> screen.setup (width=200, height=200, startx=0, starty=0)
+   # sets window to 200x200 pixels, in upper left of screen
+   >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
+   # sets window to 75% of screen by 50% of screen and centers
+
+
+.. function:: title(titlestring)
+
+   :param titlestring: a string that is shown in the titlebar of the turtle
+                       graphics window
+
+   Set title of turtle window to *titlestring*.
+
+   >>> screen.title("Welcome to the turtle zoo!")
+
+
+The public classes of the module :mod:`turtle`
+==============================================
+
+
+.. class:: RawTurtle(canvas)
+           RawPen(canvas)
+
+   :param canvas: a :class:`Tkinter.Canvas`, a :class:`ScrolledCanvas` or a
+                  :class:`TurtleScreen`
+
+    Create a turtle.  The turtle has all methods described above as "methods of
+    Turtle/RawTurtle".
 
 
 .. class:: Turtle()
 
-   Define a pen. This is essentially a synonym for ``Pen()``; :class:`Turtle` is an
-   empty subclass of :class:`Pen`.
+    Subclass of RawTurtle, has the same interface but draws on a default
+    :class:`Screen` object created automatically when needed for the first time.
 
 
-.. class:: RawPen(canvas)
+.. class:: TurtleScreen(cv)
 
-   Define a pen which draws on a canvas *canvas*. This is useful if  you want to
-   use the module to create graphics in a "real" program.
+   :param cv: a :class:`Tkinter.Canvas`
+
+   Provides screen oriented methods like :func:`setbg` etc. that are described
+   above.
+
+.. class:: Screen()
+
+   Subclass of TurtleScreen, with :ref:`four methods added <screenspecific>`.
+
+   
+.. class:: ScrolledCavas(master)
+
+   :param master: some Tkinter widget to contain the ScrolledCanvas, i.e.
+      a Tkinter-canvas with scrollbars added
+
+   Used by class Screen, which thus automatically provides a ScrolledCanvas as
+   playground for the turtles.
+
+.. class:: Shape(type_, data)
+
+   :param type\_: one of the strings "polygon", "image", "compound"
+
+   Data structure modeling shapes.  The pair ``(type_, data)`` must follow this
+   specification:
 
 
-.. _pen-rawpen-objects:
+   =========== ===========
+   *type_*     *data*
+   =========== ===========
+   "polygon"   a polygon-tuple, i.e. a tuple of pairs of coordinates
+   "image"     an image  (in this form only used internally!)
+   "compound"  ``None`` (a compund shape has to be constructed using the
+               :meth:`addcomponent` method)
+   =========== ===========
+                
+   .. method:: addcomponent(poly, fill, outline=None)
 
-Turtle, Pen and RawPen Objects
-------------------------------
+      :param poly: a polygon, i.e. a tuple of pairs of numbers
+      :param fill: a color the *poly* will be filled with
+      :param outline: a color for the poly's outline (if given)
+     
+      Example:
 
-Most of the global functions available in the module are also available as
-methods of the :class:`Turtle`, :class:`Pen` and :class:`RawPen` classes,
-affecting only the state of the given pen.
+      >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+      >>> s = Shape("compound")
+      >>> s.addcomponent(poly, "red", "blue")
+      # .. add more components and then use register_shape()
 
-The only method which is more powerful as a method is :func:`degrees`, which
-takes an optional argument letting  you specify the number of units
-corresponding to a full circle:
+      See :ref:`compoundshapes`.
 
 
-.. method:: Turtle.degrees([fullcircle])
+.. class:: Vec2D(x, y)
 
-   *fullcircle* is by default 360. This can cause the pen to have any angular units
-   whatever: give *fullcircle* ``2*pi`` for radians, or 400 for gradians.
+   A two-dimensional vector class, used as a helper class for implementing
+   turtle graphics.  May be useful for turtle graphics programs too.  Derived
+   from tuple, so a vector is a tuple!
+
+   Provides (for *a*, *b* vectors, *k* number):
+
+   * ``a + b`` vector addition
+   * ``a - b`` vector subtraction
+   * ``a * b`` inner product
+   * ``k * a`` and ``a * k`` multiplication with scalar
+   * ``abs(a)`` absolute value of a
+   * ``a.rotate(angle)`` rotation
+
+
+Help and configuration
+======================
+
+How to use help
+---------------
+
+The public methods of the Screen and Turtle classes are documented extensively
+via docstrings.  So these can be used as online-help via the Python help
+facilities:
+
+- When using IDLE, tooltips show the signatures and first lines of the
+  docstrings of typed in function-/method calls.
+
+- Calling :func:`help` on methods or functions displays the docstrings::
+
+     >>> help(Screen.bgcolor)
+     Help on method bgcolor in module turtle:
+    
+     bgcolor(self, *args) unbound turtle.Screen method
+         Set or return backgroundcolor of the TurtleScreen.
+    
+         Arguments (if given): a color string or three numbers
+         in the range 0..colormode or a 3-tuple of such numbers.
+    
+    
+           >>> screen.bgcolor("orange")
+           >>> screen.bgcolor()
+           "orange"
+           >>> screen.bgcolor(0.5,0,0.5)
+           >>> screen.bgcolor()
+           "#800080"
+    
+     >>> help(Turtle.penup)
+     Help on method penup in module turtle:
+    
+     penup(self) unbound turtle.Turtle method
+         Pull the pen up -- no drawing when moving.
+    
+         Aliases: penup | pu | up
+    
+         No argument
+    
+         >>> turtle.penup()
+
+- The docstrings of the functions which are derived from methods have a modified
+  form::
+
+     >>> help(bgcolor)
+     Help on function bgcolor in module turtle:
+    
+     bgcolor(*args)
+         Set or return backgroundcolor of the TurtleScreen.
+    
+         Arguments (if given): a color string or three numbers
+         in the range 0..colormode or a 3-tuple of such numbers.
+    
+         Example::
+    
+           >>> bgcolor("orange")
+           >>> bgcolor()
+           "orange"
+           >>> bgcolor(0.5,0,0.5)
+           >>> bgcolor()
+           "#800080"
+    
+     >>> help(penup)
+     Help on function penup in module turtle:
+    
+     penup()
+         Pull the pen up -- no drawing when moving.
+    
+         Aliases: penup | pu | up
+    
+         No argument
+    
+         Example:
+         >>> penup()
+
+These modified docstrings are created automatically together with the function
+definitions that are derived from the methods at import time.
+
+
+Translation of docstrings into different languages
+--------------------------------------------------
+
+There is a utility to create a dictionary the keys of which are the method names
+and the values of which are the docstrings of the public methods of the classes
+Screen and Turtle.
+
+.. function:: write_docstringdict(filename="turtle_docstringdict")
+
+   :param filename: a string, used as filename
+
+   Create and write docstring-dictionary to a Python script with the given
+   filename.  This function has to be called explicitly (it is not used by the
+   turtle graphics classes).  The docstring dictionary will be written to the
+   Python script :file:`{filename}.py`.  It is intended to serve as a template
+   for translation of the docstrings into different languages.
+
+If you (or your students) want to use :mod:`turtle` with online help in your
+native language, you have to translate the docstrings and save the resulting
+file as e.g. :file:`turtle_docstringdict_german.py`.
+
+If you have an appropriate entry in your :file:`turtle.cfg` file this dictionary
+will be read in at import time and will replace the original English docstrings.
+
+At the time of this writing there are docstring dictionaries in German and in
+Italian.  (Requests please to glingl@aon.at.)
+
+
+
+How to configure Screen and Turtles
+-----------------------------------
+
+The built-in default configuration mimics the appearance and behaviour of the
+old turtle module in order to retain best possible compatibility with it.
+
+If you want to use a different configuration which better reflects the features
+of this module or which better fits to your needs, e.g. for use in a classroom,
+you can prepare a configuration file ``turtle.cfg`` which will be read at import
+time and modify the configuration according to its settings.
+
+The built in configuration would correspond to the following turtle.cfg::
+
+   width = 0.5
+   height = 0.75
+   leftright = None
+   topbottom = None
+   canvwidth = 400
+   canvheight = 300
+   mode = standard
+   colormode = 1.0
+   delay = 10
+   undobuffersize = 1000
+   shape = classic
+   pencolor = black
+   fillcolor = black
+   resizemode = noresize
+   visible = True
+   language = english
+   exampleturtle = turtle
+   examplescreen = screen
+   title = Python Turtle Graphics
+   using_IDLE = False
+
+Short explanation of selected entries:
+
+- The first four lines correspond to the arguments of the :meth:`Screen.setup`
+  method.
+- Line 5 and 6 correspond to the arguments of the method
+  :meth:`Screen.screensize`.
+- *shape* can be any of the built-in shapes, e.g: arrow, turtle, etc.  For more
+  info try ``help(shape)``.
+- If you want to use no fillcolor (i.e. make the turtle transparent), you have
+  to write ``fillcolor = ""`` (but all nonempty strings must not have quotes in
+  the cfg-file).
+- If you want to reflect the turtle its state, you have to use ``resizemode =
+  auto``.
+- If you set e.g. ``language = italian`` the docstringdict
+  :file:`turtle_docstringdict_italian.py` will be loaded at import time (if
+  present on the import path, e.g. in the same directory as :mod:`turtle`.
+- The entries *exampleturtle* and *examplescreen* define the names of these
+  objects as they occur in the docstrings.  The transformation of
+  method-docstrings to function-docstrings will delete these names from the
+  docstrings.
+- *using_IDLE*: Set this to ``True`` if you regularly work with IDLE and its -n
+  switch ("no subprocess").  This will prevent :func:`exitonclick` to enter the
+  mainloop.
+
+There can be a :file:`turtle.cfg` file in the directory where :mod:`turtle` is
+stored and an additional one in the current working directory.  The latter will
+override the settings of the first one.
+
+The :file:`Demo/turtle` directory contains a :file:`turtle.cfg` file.  You can
+study it as an example and see its effects when running the demos (preferably
+not from within the demo-viewer).
+
+
+Demo scripts
+============
+
+There is a set of demo scripts in the turtledemo directory located in the
+:file:`Demo/turtle` directory in the source distribution.
+
+It contains:
+
+- a set of 15 demo scripts demonstrating differet features of the new module
+  :mod:`turtle`
+- a demo viewer :file:`turtleDemo.py` which can be used to view the sourcecode
+  of the scripts and run them at the same time. 14 of the examples can be
+  accessed via the Examples menu; all of them can also be run standalone.
+- The example :file:`turtledemo_two_canvases.py` demonstrates the simultaneous
+  use of two canvases with the turtle module.  Therefore it only can be run
+  standalone.
+- There is a :file:`turtle.cfg` file in this directory, which also serves as an
+  example for how to write and use such files.
+
+The demoscripts are:
+
++----------------+------------------------------+-----------------------+
+| Name           | Description                  | Features              |
++----------------+------------------------------+-----------------------+
+| bytedesign     | complex classical            | :func:`tracer`, delay,|
+|                | turtlegraphics pattern       | :func:`update`        |
++----------------+------------------------------+-----------------------+
+| chaos          | graphs verhust dynamics,     | world coordinates     |
+|                | proves that you must not     |                       |
+|                | trust computers' computations|                       |
++----------------+------------------------------+-----------------------+
+| clock          | analog clock showing time    | turtles as clock's    |
+|                | of your computer             | hands, ontimer        |
++----------------+------------------------------+-----------------------+
+| colormixer     | experiment with r, g, b      | :func:`ondrag`        |
++----------------+------------------------------+-----------------------+
+| fractalcurves  | Hilbert & Koch curves        | recursion             |
++----------------+------------------------------+-----------------------+
+| lindenmayer    | ethnomathematics             | L-System              |
+|                | (indian kolams)              |                       |
++----------------+------------------------------+-----------------------+
+| minimal_hanoi  | Towers of Hanoi              | Rectangular Turtles   |
+|                |                              | as Hanoi discs        |
+|                |                              | (shape, shapesize)    |
++----------------+------------------------------+-----------------------+
+| paint          | super minimalistic           | :func:`onclick`       |
+|                | drawing program              |                       |
++----------------+------------------------------+-----------------------+
+| peace          | elementary                   | turtle: appearance    |
+|                |                              | and animation         |
++----------------+------------------------------+-----------------------+
+| penrose        | aperiodic tiling with        | :func:`stamp`         |
+|                | kites and darts              |                       |
++----------------+------------------------------+-----------------------+
+| planet_and_moon| simulation of                | compound shapes,      |
+|                | gravitational system         | :class:`Vec2D`        |
++----------------+------------------------------+-----------------------+
+| tree           | a (graphical) breadth        | :func:`clone`         |
+|                | first tree (using generators)|                       |
++----------------+------------------------------+-----------------------+
+| wikipedia      | a pattern from the wikipedia | :func:`clone`,        |
+|                | article on turtle graphics   | :func:`undo`          |
++----------------+------------------------------+-----------------------+
+| yingyang       | another elementary example   | :func:`circle`        |
++----------------+------------------------------+-----------------------+
+
+Have fun!
+
+
+Changes since Python 2.6
+========================
+
+- The methods :meth:`Turtle.tracer`, :meth:`Turtle.window_width` and 
+  :meth:`Turtle.window_height` have been eliminated. 
+  Methods with these names and functionality are now available only 
+  as methods of :class:`Screen`. The functions derived from these remain
+  available. (In fact already in Python 2.6 these methods were merely 
+  duplications of the corresponding 
+  :class:`TurtleScreen`/:class:`Screen`-methods.)
+
+- The method :meth:`Turtle.fill` has been eliminated. 
+  The behaviour of :meth:`begin_fill` and :meth:`end_fill` 
+  have changed slightly: now  every filling-process must be completed with an 
+  ``end_fill()`` call.
+  
+- A method :meth:`Turtle.filling` has been added. It returns a boolean
+  value: ``True`` if a filling process is under way, ``False`` otherwise.
+  This behaviour corresponds to a ``fill()`` call without arguments in
+  Python 2.6
 
diff --git a/Lib/tkinter/turtle.py b/Lib/tkinter/turtle.py
index 3dee659..1497d2d 100644
--- a/Lib/tkinter/turtle.py
+++ b/Lib/tkinter/turtle.py
@@ -1,9 +1,31 @@
-# LogoMation-like turtle graphics
+#
+# turtle.py: a Tkinter based turtle graphics module for Python
+# Version 1.0b1 - 31. 5. 2008
+#
+# Copyright (C) 2006 - 2008  Gregor Lingl
+# email: glingl@aon.at
+#
+# This software is provided 'as-is', without any express or implied
+# warranty.  In no event will the authors be held liable for any damages
+# arising from the use of this software.
+#
+# Permission is granted to anyone to use this software for any purpose,
+# including commercial applications, and to alter it and redistribute it
+# freely, subject to the following restrictions:
+#
+# 1. The origin of this software must not be misrepresented; you must not
+#    claim that you wrote the original software. If you use this software
+#    in a product, an acknowledgment in the product documentation would be
+#    appreciated but is not required.
+# 2. Altered source versions must be plainly marked as such, and must not be
+#    misrepresented as being the original software.
+# 3. This notice may not be removed or altered from any source distribution.
+
 
 """
 Turtle graphics is a popular way for introducing programming to
 kids. It was part of the original Logo programming language developed
-by Wally Feurzeig and Seymour Papert in 1966.
+by Wally Feurzig and Seymour Papert in 1966.
 
 Imagine a robotic turtle starting at (0, 0) in the x-y plane. Give it
 the command turtle.forward(15), and it moves (on-screen!) 15 pixels in
@@ -12,945 +34,4018 @@
 
 By combining together these and similar commands, intricate shapes and
 pictures can easily be drawn.
+
+----- turtle.py
+
+This module is an extended reimplementation of turtle.py from the
+Python standard distribution up to Python 2.5. (See: http:\\www.python.org)
+
+It tries to keep the merits of turtle.py and to be (nearly) 100%
+compatible with it. This means in the first place to enable the
+learning programmer to use all the commands, classes and methods
+interactively when using the module from within IDLE run with
+the -n switch.
+
+Roughly it has the following features added:
+
+- Better animation of the turtle movements, especially of turning the
+  turtle. So the turtles can more easily be used as a visual feedback
+  instrument by the (beginning) programmer.
+
+- Different turtle shapes, gif-images as turtle shapes, user defined
+  and user controllable turtle shapes, among them compound
+  (multicolored) shapes. Turtle shapes can be stgretched and tilted, which
+  makes turtles zu very versatile geometrical objects.
+
+- Fine control over turtle movement and screen updates via delay(),
+  and enhanced tracer() and speed() methods.
+
+- Aliases for the most commonly used commands, like fd for forward etc.,
+  following the early Logo traditions. This reduces the boring work of
+  typing long sequences of commands, which often occur in a natural way
+  when kids try to program fancy pictures on their first encounter with
+  turtle graphcis.
+
+- Turtles now have an undo()-method with configurable undo-buffer.
+
+- Some simple commands/methods for creating event driven programs
+  (mouse-, key-, timer-events). Especially useful for programming games.
+
+- A scrollable Canvas class. The default scrollable Canvas can be
+  extended interactively as needed while playing around with the turtle(s).
+
+- A TurtleScreen class with methods controlling background color or
+  background image, window and canvas size and other properties of the
+  TurtleScreen.
+
+- There is a method, setworldcoordinates(), to install a user defined
+  coordinate-system for the TurtleScreen.
+
+- The implementation uses a 2-vector class named Vec2D, derived from tuple.
+  This class is public, so it can be imported by the application programmer,
+  which makes certain types of computations very natural and compact.
+
+- Appearance of the TurtleScreen and the Turtles at startup/import can be
+  configured by means of a turtle.cfg configuration file.
+  The default configuration mimics the appearance of the old turtle module.
+
+- If configured appropriately the module reads in docstrings from a docstring
+  dictionary in some different language, supplied separately  and replaces
+  the english ones by those read in. There is a utility function
+  write_docstringdict() to write a dictionary with the original (english)
+  docstrings to disc, so it can serve as a template for translations.
+
+Behind the scenes there are some features included with possible
+extensionsin in mind. These will be commented and documented elsewhere.
+
 """
 
-from math import * # Also for export
-from time import sleep
-import tkinter
+_ver = "turtle 1.0b1- - for Python 3.0   -  9. 6. 2008, 01:15"
 
-speeds = ['fastest', 'fast', 'normal', 'slow', 'slowest']
+# print(_ver)
 
-class Error(Exception):
-    pass
+import tkinter as TK
+import types
+import math
+import time
+import os
 
-class RawPen:
+from os.path import isfile, split, join
+from copy import deepcopy
 
-    def __init__(self, canvas):
-        self._canvas = canvas
-        self._items = []
-        self._tracing = 1
-        self._arrow = 0
-        self._delay = 10     # default delay for drawing
-        self._angle = 0.0
-        self.degrees()
-        self.reset()
+#from math import *    ## for compatibility with old turtle module
 
-    def degrees(self, fullcircle=360.0):
-        """ Set angle measurement units to degrees.
+_tg_classes = ['ScrolledCanvas', 'TurtleScreen', 'Screen',
+               'RawTurtle', 'Turtle', 'RawPen', 'Pen', 'Shape', 'Vec2D']
+_tg_screen_functions = ['addshape', 'bgcolor', 'bgpic', 'bye',
+        'clearscreen', 'colormode', 'delay', 'exitonclick', 'getcanvas',
+        'getshapes', 'listen', 'mode', 'onkey', 'onscreenclick', 'ontimer',
+        'register_shape', 'resetscreen', 'screensize', 'setup',
+        'setworldcoordinates', 'title', 'tracer', 'turtles', 'update',
+        'window_height', 'window_width']
+_tg_turtle_functions = ['back', 'backward', 'begin_fill', 'begin_poly', 'bk',
+        'circle', 'clear', 'clearstamp', 'clearstamps', 'clone', 'color',
+        'degrees', 'distance', 'dot', 'down', 'end_fill', 'end_poly', 'fd',
+        #'fill',
+        'fillcolor', 'forward', 'get_poly', 'getpen', 'getscreen',
+        'getturtle', 'goto', 'heading', 'hideturtle', 'home', 'ht', 'isdown',
+        'isvisible', 'left', 'lt', 'onclick', 'ondrag', 'onrelease', 'pd',
+        'pen', 'pencolor', 'pendown', 'pensize', 'penup', 'pos', 'position',
+        'pu', 'radians', 'right', 'reset', 'resizemode', 'rt',
+        'seth', 'setheading', 'setpos', 'setposition', 'settiltangle',
+        'setundobuffer', 'setx', 'sety', 'shape', 'shapesize', 'showturtle',
+        'speed', 'st', 'stamp', 'tilt', 'tiltangle', 'towards', #'tracer',
+        'turtlesize', 'undo', 'undobufferentries', 'up', 'width',
+        #'window_height', 'window_width',
+        'write', 'xcor', 'ycor']
+_tg_utilities = ['write_docstringdict', 'done', 'mainloop']
+##_math_functions = ['acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'cosh',
+##        'e', 'exp', 'fabs', 'floor', 'fmod', 'frexp', 'hypot', 'ldexp', 'log',
+##        'log10', 'modf', 'pi', 'pow', 'sin', 'sinh', 'sqrt', 'tan', 'tanh']
 
-        Example:
-        >>> turtle.degrees()
-        """
-        # Don't try to change _angle if it is 0, because
-        # _fullcircle might not be set, yet
-        if self._angle:
-            self._angle = (self._angle / self._fullcircle) * fullcircle
-        self._fullcircle = fullcircle
-        self._invradian = pi / (fullcircle * 0.5)
+__all__ = (_tg_classes + _tg_screen_functions + _tg_turtle_functions +
+           _tg_utilities) # + _math_functions)
 
-    def radians(self):
-        """ Set the angle measurement units to radians.
+_alias_list = ['addshape', 'backward', 'bk', 'fd', 'ht', 'lt', 'pd', 'pos',
+               'pu', 'rt', 'seth', 'setpos', 'setposition', 'st',
+               'turtlesize', 'up', 'width']
 
-        Example:
-        >>> turtle.radians()
-        """
-        self.degrees(2.0*pi)
+_CFG = {"width" : 0.5,               # Screen
+        "height" : 0.75,
+        "canvwidth" : 400,
+        "canvheight": 300,
+        "leftright": None,
+        "topbottom": None,
+        "mode": "standard",          # TurtleScreen
+        "colormode": 1.0,
+        "delay": 10,
+        "undobuffersize": 1000,      # RawTurtle
+        "shape": "classic",
+        "pencolor" : "black",
+        "fillcolor" : "black",
+        "resizemode" : "noresize",
+        "visible" : True,
+        "language": "english",        # docstrings
+        "exampleturtle": "turtle",
+        "examplescreen": "screen",
+        "title": "Python Turtle Graphics",
+        "using_IDLE": False
+       }
 
-    def reset(self):
-        """ Clear the screen, re-center the pen, and set variables to
-        the default values.
+##print "cwd:", os.getcwd()
+##print "__file__:", __file__
+##
+##def show(dictionary):
+##    print "=========================="
+##    for key in sorted(dictionary.keys()):
+##        print key, ":", dictionary[key]
+##    print "=========================="
+##    print
 
-        Example:
-        >>> turtle.position()
-        [0.0, -22.0]
-        >>> turtle.heading()
-        100.0
-        >>> turtle.reset()
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.heading()
-        0.0
-        """
-        canvas = self._canvas
-        self._canvas.update()
-        width = canvas.winfo_width()
-        height = canvas.winfo_height()
-        if width <= 1:
-            width = canvas['width']
-        if height <= 1:
-            height = canvas['height']
-        self._origin = float(width)/2.0, float(height)/2.0
-        self._position = self._origin
-        self._angle = 0.0
-        self._drawing = 1
-        self._width = 1
-        self._color = "black"
-        self._filling = 0
-        self._path = []
-        self.clear()
-        canvas._root().tkraise()
-
-    def clear(self):
-        """ Clear the screen. The turtle does not move.
-
-        Example:
-        >>> turtle.clear()
-        """
-        self.fill(0)
-        canvas = self._canvas
-        items = self._items
-        self._items = []
-        for item in items:
-            canvas.delete(item)
-        self._delete_turtle()
-        self._draw_turtle()
-
-    def tracer(self, flag):
-        """ Set tracing on if flag is True, and off if it is False.
-        Tracing means line are drawn more slowly, with an
-        animation of an arrow along the line.
-
-        Example:
-        >>> turtle.tracer(False)   # turns off Tracer
-        """
-        self._tracing = flag
-        if not self._tracing:
-            self._delete_turtle()
-        self._draw_turtle()
-
-    def forward(self, distance):
-        """ Go forward distance steps.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.forward(25)
-        >>> turtle.position()
-        [25.0, 0.0]
-        >>> turtle.forward(-75)
-        >>> turtle.position()
-        [-50.0, 0.0]
-        """
-        x0, y0 = start = self._position
-        x1 = x0 + distance * cos(self._angle*self._invradian)
-        y1 = y0 - distance * sin(self._angle*self._invradian)
-        self._goto(x1, y1)
-
-    def backward(self, distance):
-        """ Go backwards distance steps.
-
-        The turtle's heading does not change.
-
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.backward(30)
-        >>> turtle.position()
-        [-30.0, 0.0]
-        """
-        self.forward(-distance)
-
-    def left(self, angle):
-        """ Turn left angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
-
-        When viewed from above, the turning happens in-place around
-        its front tip.
-
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.left(45)
-        >>> turtle.heading()
-        67.0
-        """
-        self._angle = (self._angle + angle) % self._fullcircle
-        self._draw_turtle()
-
-    def right(self, angle):
-        """ Turn right angle units (units are by default degrees,
-        but can be set via the degrees() and radians() functions.)
-
-        When viewed from above, the turning happens in-place around
-        its front tip.
-
-        Example:
-        >>> turtle.heading()
-        22
-        >>> turtle.right(45)
-        >>> turtle.heading()
-        337.0
-        """
-        self.left(-angle)
-
-    def up(self):
-        """ Pull the pen up -- no drawing when moving.
-
-        Example:
-        >>> turtle.up()
-        """
-        self._drawing = 0
-
-    def down(self):
-        """ Put the pen down -- draw when moving.
-
-        Example:
-        >>> turtle.down()
-        """
-        self._drawing = 1
-
-    def width(self, width):
-        """ Set the line to thickness to width.
-
-        Example:
-        >>> turtle.width(10)
-        """
-        self._width = float(width)
-
-    def color(self, *args):
-        """ Set the pen color.
-
-        Three input formats are allowed:
-
-            color(s)
-            s is a Tk specification string, such as "red" or "yellow"
-
-            color((r, g, b))
-            *a tuple* of r, g, and b, which represent, an RGB color,
-            and each of r, g, and b are in the range [0..1]
-
-            color(r, g, b)
-            r, g, and b represent an RGB color, and each of r, g, and b
-            are in the range [0..1]
-
-        Example:
-
-        >>> turtle.color('brown')
-        >>> tup = (0.2, 0.8, 0.55)
-        >>> turtle.color(tup)
-        >>> turtle.color(0, .5, 0)
-        """
-        if not args:
-            raise Error("no color arguments")
-        if len(args) == 1:
-            color = args[0]
-            if type(color) == type(""):
-                # Test the color first
-                try:
-                    id = self._canvas.create_line(0, 0, 0, 0, fill=color)
-                except tkinter.TclError:
-                    raise Error("bad color string: %r" % (color,))
-                self._set_color(color)
-                return
-            try:
-                r, g, b = color
-            except:
-                raise Error("bad color sequence: %r" % (color,))
+def config_dict(filename):
+    """Convert content of config-file into dictionary."""
+    f = open(filename, "r")
+    cfglines = f.readlines()
+    f.close()
+    cfgdict = {}
+    for line in cfglines:
+        line = line.strip()
+        if not line or line.startswith("#"):
+            continue
+        try:
+            key, value = line.split("=")
+        except:
+            print("Bad line in config-file %s:\n%s" % (filename,line))
+            continue
+        key = key.strip()
+        value = value.strip()
+        if value in ["True", "False", "None", "''", '""']:
+            value = eval(value)
         else:
             try:
-                r, g, b = args
+                if "." in value:
+                    value = float(value)
+                else:
+                    value = int(value)
             except:
-                raise Error("bad color arguments: %r" % (args,))
-        assert 0 <= r <= 1
-        assert 0 <= g <= 1
-        assert 0 <= b <= 1
-        x = 255.0
-        y = 0.5
-        self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))
+                pass # value need not be converted
+        cfgdict[key] = value
+    return cfgdict
 
-    def _set_color(self,color):
-        self._color = color
-        self._draw_turtle()
+def readconfig(cfgdict):
+    """Read config-files, change configuration-dict accordingly.
 
-    def write(self, text, move=False):
-        """ Write text at the current pen position.
+    If there is a turtle.cfg file in the current working directory,
+    read it from there. If this contains an importconfig-value,
+    say 'myway', construct filename turtle_mayway.cfg else use
+    turtle.cfg and read it from the import-directory, where
+    turtle.py is located.
+    Update configuration dictionary first according to config-file,
+    in the import directory, then according to config-file in the
+    current working directory.
+    If no config-file is found, the default configuration is used.
+    """
+    default_cfg = "turtle.cfg"
+    cfgdict1 = {}
+    cfgdict2 = {}
+    if isfile(default_cfg):
+        cfgdict1 = config_dict(default_cfg)
+        #print "1. Loading config-file %s from: %s" % (default_cfg, os.getcwd())
+    if "importconfig" in cfgdict1:
+        default_cfg = "turtle_%s.cfg" % cfgdict1["importconfig"]
+    try:
+        head, tail = split(__file__)
+        cfg_file2 = join(head, default_cfg)
+    except:
+        cfg_file2 = ""
+    if isfile(cfg_file2):
+        #print "2. Loading config-file %s:" % cfg_file2
+        cfgdict2 = config_dict(cfg_file2)
+##    show(_CFG)
+##    show(cfgdict2)
+    _CFG.update(cfgdict2)
+##    show(_CFG)
+##    show(cfgdict1)
+    _CFG.update(cfgdict1)
+##    show(_CFG)
 
-        If move is true, the pen is moved to the bottom-right corner
-        of the text. By default, move is False.
+try:
+    readconfig(_CFG)
+except:
+    print ("No configfile read, reason unknown")
+
+
+class Vec2D(tuple):
+    """A 2 dimensional vector class, used as a helper class
+    for implementing turtle graphics.
+    May be useful for turtle graphics programs also.
+    Derived from tuple, so a vector is a tuple!
+
+    Provides (for a, b vectors, k number):
+       a+b vector addition
+       a-b vector subtraction
+       a*b inner product
+       k*a and a*k multiplication with scalar
+       |a| absolute value of a
+       a.rotate(angle) rotation
+    """
+    def __new__(cls, x, y):
+        return tuple.__new__(cls, (x, y))
+    def __add__(self, other):
+        return Vec2D(self[0]+other[0], self[1]+other[1])
+    def __mul__(self, other):
+        if isinstance(other, Vec2D):
+            return self[0]*other[0]+self[1]*other[1]
+        return Vec2D(self[0]*other, self[1]*other)
+    def __rmul__(self, other):
+        if isinstance(other, int) or isinstance(other, float):
+            return Vec2D(self[0]*other, self[1]*other)
+    def __sub__(self, other):
+        return Vec2D(self[0]-other[0], self[1]-other[1])
+    def __neg__(self):
+        return Vec2D(-self[0], -self[1])
+    def __abs__(self):
+        return (self[0]**2 + self[1]**2)**0.5
+    def rotate(self, angle):
+        """rotate self counterclockwise by angle
+        """
+        perp = Vec2D(-self[1], self[0])
+        angle = angle * math.pi / 180.0
+        c, s = math.cos(angle), math.sin(angle)
+        return Vec2D(self[0]*c+perp[0]*s, self[1]*c+perp[1]*s)
+    def __getnewargs__(self):
+        return (self[0], self[1])
+    def __repr__(self):
+        return "(%.2f,%.2f)" % self
+
+
+##############################################################################
+### From here up to line    : Tkinter - Interface for turtle.py            ###
+### May be replaced by an interface to some different graphcis-toolkit     ###
+##############################################################################
+
+## helper functions for Scrolled Canvas, to forward Canvas-methods
+## to ScrolledCanvas class
+
+def __methodDict(cls, _dict):
+    """helper function for Scrolled Canvas"""
+    baseList = list(cls.__bases__)
+    baseList.reverse()
+    for _super in baseList:
+        __methodDict(_super, _dict)
+    for key, value in cls.__dict__.items():
+        if type(value) == types.FunctionType:
+            _dict[key] = value
+
+def __methods(cls):
+    """helper function for Scrolled Canvas"""
+    _dict = {}
+    __methodDict(cls, _dict)
+    return _dict.keys()
+
+__stringBody = (
+    'def %(method)s(self, *args, **kw): return ' +
+    'self.%(attribute)s.%(method)s(*args, **kw)')
+
+def __forwardmethods(fromClass, toClass, toPart, exclude = ()):
+    ### MANY CHANGES ###
+    _dict_1 = {}
+    __methodDict(toClass, _dict_1)
+    _dict = {}
+    mfc = __methods(fromClass)
+    for ex in _dict_1.keys():
+        if ex[:1] == '_' or ex[-1:] == '_' or ex in exclude or ex in mfc:
+            pass
+        else:
+            _dict[ex] = _dict_1[ex]
+
+    for method, func in _dict.items():
+        d = {'method': method, 'func': func}
+        if isinstance(toPart, str):
+            execString = \
+                __stringBody % {'method' : method, 'attribute' : toPart}
+        exec(execString, d)
+        setattr(fromClass, method, d[method])   ### NEWU!
+
+
+class ScrolledCanvas(TK.Frame):
+    """Modeled after the scrolled canvas class from Grayons's Tkinter book.
+
+    Used as the default canvas, which pops up automatically when
+    using turtle graphics functions or the Turtle class.
+    """
+    def __init__(self, master, width=500, height=350,
+                                          canvwidth=600, canvheight=500):
+        TK.Frame.__init__(self, master, width=width, height=height)
+        self._root = self.winfo_toplevel()
+        self.width, self.height = width, height
+        self.canvwidth, self.canvheight = canvwidth, canvheight
+        self.bg = "white"
+        self._canvas = TK.Canvas(master, width=width, height=height,
+                                 bg=self.bg, relief=TK.SUNKEN, borderwidth=2)
+        self.hscroll = TK.Scrollbar(master, command=self._canvas.xview,
+                                    orient=TK.HORIZONTAL)
+        self.vscroll = TK.Scrollbar(master, command=self._canvas.yview)
+        self._canvas.configure(xscrollcommand=self.hscroll.set,
+                               yscrollcommand=self.vscroll.set)
+        self.rowconfigure(0, weight=1, minsize=0)
+        self.columnconfigure(0, weight=1, minsize=0)
+        self._canvas.grid(padx=1, in_ = self, pady=1, row=0,
+                column=0, rowspan=1, columnspan=1, sticky='news')
+        self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+                column=1, rowspan=1, columnspan=1, sticky='news')
+        self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+                column=0, rowspan=1, columnspan=1, sticky='news')
+        self.reset()
+        self._root.bind('<Configure>', self.onResize)
+
+    def reset(self, canvwidth=None, canvheight=None, bg = None):
+        """Ajust canvas and scrollbars according to given canvas size."""
+        if canvwidth:
+            self.canvwidth = canvwidth
+        if canvheight:
+            self.canvheight = canvheight
+        if bg:
+            self.bg = bg
+        self._canvas.config(bg=bg,
+                        scrollregion=(-self.canvwidth//2, -self.canvheight//2,
+                                       self.canvwidth//2, self.canvheight//2))
+        self._canvas.xview_moveto(0.5*(self.canvwidth - self.width + 30) /
+                                                               self.canvwidth)
+        self._canvas.yview_moveto(0.5*(self.canvheight- self.height + 30) /
+                                                              self.canvheight)
+        self.adjustScrolls()
+
+
+    def adjustScrolls(self):
+        """ Adjust scrollbars according to window- and canvas-size.
+        """
+        cwidth = self._canvas.winfo_width()
+        cheight = self._canvas.winfo_height()
+        self._canvas.xview_moveto(0.5*(self.canvwidth-cwidth)/self.canvwidth)
+        self._canvas.yview_moveto(0.5*(self.canvheight-cheight)/self.canvheight)
+        if cwidth < self.canvwidth or cheight < self.canvheight:
+            self.hscroll.grid(padx=1, in_ = self, pady=1, row=1,
+                              column=0, rowspan=1, columnspan=1, sticky='news')
+            self.vscroll.grid(padx=1, in_ = self, pady=1, row=0,
+                              column=1, rowspan=1, columnspan=1, sticky='news')
+        else:
+            self.hscroll.grid_forget()
+            self.vscroll.grid_forget()
+
+    def onResize(self, event):
+        """self-explanatory"""
+        self.adjustScrolls()
+
+    def bbox(self, *args):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        return self._canvas.bbox(*args)
+
+    def cget(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        return self._canvas.cget(*args, **kwargs)
+
+    def config(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.config(*args, **kwargs)
+
+    def bind(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.bind(*args, **kwargs)
+
+    def unbind(self, *args, **kwargs):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.unbind(*args, **kwargs)
+
+    def focus_force(self):
+        """ 'forward' method, which canvas itself has inherited...
+        """
+        self._canvas.focus_force()
+
+__forwardmethods(ScrolledCanvas, TK.Canvas, '_canvas')
+
+
+class _Root(TK.Tk):
+    """Root class for Screen based on Tkinter."""
+    def __init__(self):
+        TK.Tk.__init__(self)
+
+    def setupcanvas(self, width, height, cwidth, cheight):
+        self._canvas = ScrolledCanvas(self, width, height, cwidth, cheight)
+        self._canvas.pack(expand=1, fill="both")
+
+    def _getcanvas(self):
+        return self._canvas
+
+    def set_geometry(self, width, height, startx, starty):
+        self.geometry("%dx%d%+d%+d"%(width, height, startx, starty))
+
+    def ondestroy(self, destroy):
+        self.wm_protocol("WM_DELETE_WINDOW", destroy)
+
+    def win_width(self):
+        return self.winfo_screenwidth()
+
+    def win_height(self):
+        return self.winfo_screenheight()
+
+Canvas = TK.Canvas
+
+
+class TurtleScreenBase(object):
+    """Provide the basic graphics functionality.
+       Interface between Tkinter and turtle.py.
+
+       To port turtle.py to some different graphics toolkit
+       a corresponding TurtleScreenBase class has to be implemented.
+    """
+
+    @staticmethod
+    def _blankimage():
+        """return a blank image object
+        """
+        img = TK.PhotoImage(width=1, height=1)
+        img.blank()
+        return img
+
+    @staticmethod
+    def _image(filename):
+        """return an image object containing the
+        imagedata from a gif-file named filename.
+        """
+        return TK.PhotoImage(file=filename)
+
+    def __init__(self, cv):
+        self.cv = cv
+        if isinstance(cv, ScrolledCanvas):
+            w = self.cv.canvwidth
+            h = self.cv.canvheight
+        else:  # expected: ordinary TK.Canvas
+            w = int(self.cv.cget("width"))
+            h = int(self.cv.cget("height"))
+            self.cv.config(scrollregion = (-w//2, -h//2, w//2, h//2 ))
+        self.canvwidth = w
+        self.canvheight = h
+        self.xscale = self.yscale = 1.0
+
+    def _createpoly(self):
+        """Create an invisible polygon item on canvas self.cv)
+        """
+        return self.cv.create_polygon((0, 0, 0, 0, 0, 0), fill="", outline="")
+
+    def _drawpoly(self, polyitem, coordlist, fill=None,
+                  outline=None, width=None, top=False):
+        """Configure polygonitem polyitem according to provided
+        arguments:
+        coordlist is sequence of coordinates
+        fill is filling color
+        outline is outline color
+        top is a boolean value, which specifies if polyitem
+        will be put on top of the canvas' displaylist so it
+        will not be covered by other items.
+        """
+        cl = []
+        for x, y in coordlist:
+            cl.append(x * self.xscale)
+            cl.append(-y * self.yscale)
+        self.cv.coords(polyitem, *cl)
+        if fill is not None:
+            self.cv.itemconfigure(polyitem, fill=fill)
+        if outline is not None:
+            self.cv.itemconfigure(polyitem, outline=outline)
+        if width is not None:
+            self.cv.itemconfigure(polyitem, width=width)
+        if top:
+            self.cv.tag_raise(polyitem)
+
+    def _createline(self):
+        """Create an invisible line item on canvas self.cv)
+        """
+        return self.cv.create_line(0, 0, 0, 0, fill="", width=2,
+                                   capstyle = TK.ROUND)
+
+    def _drawline(self, lineitem, coordlist=None,
+                  fill=None, width=None, top=False):
+        """Configure lineitem according to provided arguments:
+        coordlist is sequence of coordinates
+        fill is drawing color
+        width is width of drawn line.
+        top is a boolean value, which specifies if polyitem
+        will be put on top of the canvas' displaylist so it
+        will not be covered by other items.
+        """
+        if coordlist is not None:
+            cl = []
+            for x, y in coordlist:
+                cl.append(x * self.xscale)
+                cl.append(-y * self.yscale)
+            self.cv.coords(lineitem, *cl)
+        if fill is not None:
+            self.cv.itemconfigure(lineitem, fill=fill)
+        if width is not None:
+            self.cv.itemconfigure(lineitem, width=width)
+        if top:
+            self.cv.tag_raise(lineitem)
+
+    def _delete(self, item):
+        """Delete graphics item from canvas.
+        If item is"all" delete all graphics items.
+        """
+        self.cv.delete(item)
+
+    def _update(self):
+        """Redraw graphics items on canvas
+        """
+        self.cv.update()
+
+    def _delay(self, delay):
+        """Delay subsequent canvas actions for delay ms."""
+        self.cv.after(delay)
+
+    def _iscolorstring(self, color):
+        """Check if the string color is a legal Tkinter color string.
+        """
+        try:
+            rgb = self.cv.winfo_rgb(color)
+            ok = True
+        except TK.TclError:
+            ok = False
+        return ok
+
+    def _bgcolor(self, color=None):
+        """Set canvas' backgroundcolor if color is not None,
+        else return backgroundcolor."""
+        if color is not None:
+            self.cv.config(bg = color)
+            self._update()
+        else:
+            return self.cv.cget("bg")
+
+    def _write(self, pos, txt, align, font, pencolor):
+        """Write txt at pos in canvas with specified font
+        and color.
+        Return text item and x-coord of right bottom corner
+        of text's bounding box."""
+        x, y = pos
+        x = x * self.xscale
+        y = y * self.yscale
+        anchor = {"left":"sw", "center":"s", "right":"se" }
+        item = self.cv.create_text(x-1, -y, text = txt, anchor = anchor[align],
+                                        fill = pencolor, font = font)
+        x0, y0, x1, y1 = self.cv.bbox(item)
+        self.cv.update()
+        return item, x1-1
+
+##    def _dot(self, pos, size, color):
+##        """may be implemented for some other graphics toolkit"""
+
+    def _onclick(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-click event on turtle.
+        fun must be a function with two arguments, the coordinates
+        of the clicked point on the canvas.
+        num, the number of the mouse-button defaults to 1
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button-%s>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.tag_bind(item, "<Button-%s>" % num, eventfun, add)
+
+    def _onrelease(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-button-release event on turtle.
+        fun must be a function with two arguments, the coordinates
+        of the point on the canvas where mouse button is released.
+        num, the number of the mouse-button defaults to 1
+
+        If a turtle is clicked, first _onclick-event will be performed,
+        then _onscreensclick-event.
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button%s-ButtonRelease>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.tag_bind(item, "<Button%s-ButtonRelease>" % num,
+                             eventfun, add)
+
+    def _ondrag(self, item, fun, num=1, add=None):
+        """Bind fun to mouse-move-event (with pressed mouse button) on turtle.
+        fun must be a function with two arguments, the coordinates of the
+        actual mouse position on the canvas.
+        num, the number of the mouse-button defaults to 1
+
+        Every sequence of mouse-move-events on a turtle is preceded by a
+        mouse-click event on that turtle.
+        """
+        if fun is None:
+            self.cv.tag_unbind(item, "<Button%s-Motion>" % num)
+        else:
+            def eventfun(event):
+                try:
+                    x, y = (self.cv.canvasx(event.x)/self.xscale,
+                           -self.cv.canvasy(event.y)/self.yscale)
+                    fun(x, y)
+                except:
+                    pass
+            self.cv.tag_bind(item, "<Button%s-Motion>" % num, eventfun, add)
+
+    def _onscreenclick(self, fun, num=1, add=None):
+        """Bind fun to mouse-click event on canvas.
+        fun must be a function with two arguments, the coordinates
+        of the clicked point on the canvas.
+        num, the number of the mouse-button defaults to 1
+
+        If a turtle is clicked, first _onclick-event will be performed,
+        then _onscreensclick-event.
+        """
+        if fun is None:
+            self.cv.unbind("<Button-%s>" % num)
+        else:
+            def eventfun(event):
+                x, y = (self.cv.canvasx(event.x)/self.xscale,
+                        -self.cv.canvasy(event.y)/self.yscale)
+                fun(x, y)
+            self.cv.bind("<Button-%s>" % num, eventfun, add)
+
+    def _onkey(self, fun, key):
+        """Bind fun to key-release event of key.
+        Canvas must have focus. See method listen
+        """
+        if fun is None:
+            self.cv.unbind("<KeyRelease-%s>" % key, None)
+        else:
+            def eventfun(event):
+                fun()
+            self.cv.bind("<KeyRelease-%s>" % key, eventfun)
+
+    def _listen(self):
+        """Set focus on canvas (in order to collect key-events)
+        """
+        self.cv.focus_force()
+
+    def _ontimer(self, fun, t):
+        """Install a timer, which calls fun after t milliseconds.
+        """
+        if t == 0:
+            self.cv.after_idle(fun)
+        else:
+            self.cv.after(t, fun)
+
+    def _createimage(self, image):
+        """Create and return image item on canvas.
+        """
+        return self.cv.create_image(0, 0, image=image)
+
+    def _drawimage(self, item, pos, image):
+        """Configure image item as to draw image object
+        at position (x,y) on canvas)
+        """
+        x, y = pos
+        self.cv.coords(item, (x * self.xscale, -y * self.yscale))
+        self.cv.itemconfig(item, image=image)
+
+    def _setbgpic(self, item, image):
+        """Configure image item as to draw image object
+        at center of canvas. Set item to the first item
+        in the displaylist, so it will be drawn below
+        any other item ."""
+        self.cv.itemconfig(item, image=image)
+        self.cv.tag_lower(item)
+
+    def _type(self, item):
+        """Return 'line' or 'polygon' or 'image' depending on
+        type of item.
+        """
+        return self.cv.type(item)
+
+    def _pointlist(self, item):
+        """returns list of coordinate-pairs of points of item
+        Example (for insiders):
+        >>> from turtle import *
+        >>> getscreen()._pointlist(getturtle().turtle._item)
+        [(0.0, 9.9999999999999982), (0.0, -9.9999999999999982),
+        (9.9999999999999982, 0.0)]
+        >>> """
+        cl = list(self.cv.coords(item))
+        pl = [(cl[i], -cl[i+1]) for i in range(0, len(cl), 2)]
+        return  pl
+
+    def _setscrollregion(self, srx1, sry1, srx2, sry2):
+        self.cv.config(scrollregion=(srx1, sry1, srx2, sry2))
+
+    def _rescale(self, xscalefactor, yscalefactor):
+        items = self.cv.find_all()
+        for item in items:
+            coordinates = list(self.cv.coords(item))
+            newcoordlist = []
+            while coordinates:
+                x, y = coordinates[:2]
+                newcoordlist.append(x * xscalefactor)
+                newcoordlist.append(y * yscalefactor)
+                coordinates = coordinates[2:]
+            self.cv.coords(item, *newcoordlist)
+
+    def _resize(self, canvwidth=None, canvheight=None, bg=None):
+        """Resize the canvas, the turtles are drawing on. Does
+        not alter the drawing window.
+        """
+        # needs amendment
+        if not isinstance(self.cv, ScrolledCanvas):
+            return self.canvwidth, self.canvheight
+        if canvwidth is None and canvheight is None and bg is None:
+            return self.cv.canvwidth, self.cv.canvheight
+        if canvwidth is not None:
+            self.canvwidth = canvwidth
+        if canvheight is not None:
+            self.canvheight = canvheight
+        self.cv.reset(canvwidth, canvheight, bg)
+
+    def _window_size(self):
+        """ Return the width and height of the turtle window.
+        """
+        width = self.cv.winfo_width()
+        if width <= 1:  # the window isn't managed by a geometry manager
+            width = self.cv['width']
+        height = self.cv.winfo_height()
+        if height <= 1: # the window isn't managed by a geometry manager
+            height = self.cv['height']
+        return width, height
+
+
+##############################################################################
+###                  End of Tkinter - interface                            ###
+##############################################################################
+
+
+class Terminator (Exception):
+    """Will be raised in TurtleScreen.update, if _RUNNING becomes False.
+
+    Thus stops execution of turtle graphics script. Main purpose: use in
+    in the Demo-Viewer turtle.Demo.py.
+    """
+    pass
+
+
+class TurtleGraphicsError(Exception):
+    """Some TurtleGraphics Error
+    """
+
+
+class Shape(object):
+    """Data structure modeling shapes.
+
+    attribute _type is one of "polygon", "image", "compound"
+    attribute _data is - depending on _type a poygon-tuple,
+    an image or a list constructed using the addcomponent method.
+    """
+    def __init__(self, type_, data=None):
+        self._type = type_
+        if type_ == "polygon":
+            if isinstance(data, list):
+                data = tuple(data)
+        elif type_ == "image":
+            if isinstance(data, str):
+                if data.lower().endswith(".gif") and isfile(data):
+                    data = TurtleScreen._image(data)
+                # else data assumed to be Photoimage
+        elif type_ == "compound":
+            data = []
+        else:
+            raise TurtleGraphicsError("There is no shape type %s" % type_)
+        self._data = data
+
+    def addcomponent(self, poly, fill, outline=None):
+        """Add component to a shape of type compound.
+
+        Arguments: poly is a polygon, i. e. a tuple of number pairs.
+        fill is the fillcolor of the component,
+        outline is the outline color of the component.
+
+        call (for a Shapeobject namend s):
+        --   s.addcomponent(((0,0), (10,10), (-10,10)), "red", "blue")
 
         Example:
-        >>> turtle.write('The race is on!')
-        >>> turtle.write('Home = (0, 0)', True)
+        >>> poly = ((0,0),(10,-5),(0,10),(-10,-5))
+        >>> s = Shape("compound")
+        >>> s.addcomponent(poly, "red", "blue")
+        ### .. add more components and then use register_shape()
         """
-        x, y  = self._position
-        x = x-1 # correction -- calibrated for Windows
-        item = self._canvas.create_text(x, y,
-                                        text=str(text), anchor="sw",
-                                        fill=self._color)
-        self._items.append(item)
-        if move:
-            x0, y0, x1, y1 = self._canvas.bbox(item)
-            self._goto(x1, y1)
-        self._draw_turtle()
+        if self._type != "compound":
+            raise TurtleGraphicsError("Cannot add component to %s Shape"
+                                                                % self._type)
+        if outline is None:
+            outline = fill
+        self._data.append([poly, fill, outline])
 
-    def fill(self, flag):
-        """ Call fill(1) before drawing the shape you
-         want to fill, and fill(0) when done.
 
-        Example:
-        >>> turtle.fill(1)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.fill(0)
+class Tbuffer(object):
+    """Ring buffer used as undobuffer for RawTurtle objects."""
+    def __init__(self, bufsize=10):
+        self.bufsize = bufsize
+        self.buffer = [[None]] * bufsize
+        self.ptr = -1
+        self.cumulate = False
+    def reset(self, bufsize=None):
+        if bufsize is None:
+            for i in range(self.bufsize):
+                self.buffer[i] = [None]
+        else:
+            self.bufsize = bufsize
+            self.buffer = [[None]] * bufsize
+        self.ptr = -1
+    def push(self, item):
+        if self.bufsize > 0:
+            if not self.cumulate:
+                self.ptr = (self.ptr + 1) % self.bufsize
+                self.buffer[self.ptr] = item
+            else:
+                self.buffer[self.ptr].append(item)
+    def pop(self):
+        if self.bufsize > 0:
+            item = self.buffer[self.ptr]
+            if item is None:
+                return None
+            else:
+                self.buffer[self.ptr] = [None]
+                self.ptr = (self.ptr - 1) % self.bufsize
+                return (item)
+    def nr_of_items(self):
+        return self.bufsize - self.buffer.count([None])
+    def __repr__(self):
+        return str(self.buffer) + " " + str(self.ptr)
+
+
+
+class TurtleScreen(TurtleScreenBase):
+    """Provides screen oriented methods like setbg etc.
+
+    Only relies upon the methods of TurtleScreenBase and NOT
+    upon components of the underlying graphics toolkit -
+    which is Tkinter in this case.
+    """
+#    _STANDARD_DELAY = 5
+    _RUNNING = True
+
+    def __init__(self, cv, mode=_CFG["mode"],
+                 colormode=_CFG["colormode"], delay=_CFG["delay"]):
+        self._shapes = {
+                   "arrow" : Shape("polygon", ((-10,0), (10,0), (0,10))),
+                  "turtle" : Shape("polygon", ((0,16), (-2,14), (-1,10), (-4,7),
+                              (-7,9), (-9,8), (-6,5), (-7,1), (-5,-3), (-8,-6),
+                              (-6,-8), (-4,-5), (0,-7), (4,-5), (6,-8), (8,-6),
+                              (5,-3), (7,1), (6,5), (9,8), (7,9), (4,7), (1,10),
+                              (2,14))),
+                  "circle" : Shape("polygon", ((10,0), (9.51,3.09), (8.09,5.88),
+                              (5.88,8.09), (3.09,9.51), (0,10), (-3.09,9.51),
+                              (-5.88,8.09), (-8.09,5.88), (-9.51,3.09), (-10,0),
+                              (-9.51,-3.09), (-8.09,-5.88), (-5.88,-8.09),
+                              (-3.09,-9.51), (-0.00,-10.00), (3.09,-9.51),
+                              (5.88,-8.09), (8.09,-5.88), (9.51,-3.09))),
+                  "square" : Shape("polygon", ((10,-10), (10,10), (-10,10),
+                              (-10,-10))),
+                "triangle" : Shape("polygon", ((10,-5.77), (0,11.55),
+                              (-10,-5.77))),
+                  "classic": Shape("polygon", ((0,0),(-5,-9),(0,-7),(5,-9))),
+                   "blank" : Shape("image", self._blankimage())
+                  }
+
+        self._bgpics = {"nopic" : ""}
+
+        TurtleScreenBase.__init__(self, cv)
+        self._mode = mode
+        self._delayvalue = delay
+        self._colormode = _CFG["colormode"]
+        self._keys = []
+        self.clear()
+
+    def clear(self):
+        """Delete all drawings and all turtles from the TurtleScreen.
+
+        Reset empty TurtleScreen to it's initial state: white background,
+        no backgroundimage, no eventbindings and tracing on.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        screen.clear()
+
+        Note: this method is not available as function.
         """
-        if self._filling:
-            path = tuple(self._path)
-            smooth = self._filling < 0
-            if len(path) > 2:
-                item = self._canvas._create('polygon', path,
-                                            {'fill': self._color,
-                                             'smooth': smooth})
-                self._items.append(item)
-        self._path = []
-        self._filling = flag
-        if flag:
-            self._path.append(self._position)
+        self._delayvalue = _CFG["delay"]
+        self._colormode = _CFG["colormode"]
+        self._delete("all")
+        self._bgpic = self._createimage("")
+        self._bgpicname = "nopic"
+        self._tracing = 1
+        self._updatecounter = 0
+        self._turtles = []
+        self.bgcolor("white")
+        for btn in 1, 2, 3:
+            self.onclick(None, btn)
+        for key in self._keys[:]:
+            self.onkey(None, key)
+        Turtle._pen = None
 
-    def begin_fill(self):
-        """ Called just before drawing a shape to be filled.
-            Must eventually be followed by a corresponding end_fill() call.
-            Otherwise it will be ignored.
+    def mode(self, mode=None):
+        """Set turtle-mode ('standard', 'logo' or 'world') and perform reset.
 
-        Example:
-        >>> turtle.begin_fill()
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.end_fill()
+        Optional argument:
+        mode -- on of the strings 'standard', 'logo' or 'world'
+
+        Mode 'standard' is compatible with turtle.py.
+        Mode 'logo' is compatible with most Logo-Turtle-Graphics.
+        Mode 'world' uses userdefined 'worldcoordinates'. *Attention*: in
+        this mode angles appear distorted if x/y unit-ratio doesn't equal 1.
+        If mode is not given, return the current mode.
+
+             Mode      Initial turtle heading     positive angles
+         ------------|-------------------------|-------------------
+          'standard'    to the right (east)       counterclockwise
+            'logo'        upward    (north)         clockwise
+
+        Examples:
+        >>> mode('logo')   # resets turtle heading to north
+        >>> mode()
+        'logo'
         """
-        self._path = [self._position]
-        self._filling = 1
+        if mode == None:
+            return self._mode
+        mode = mode.lower()
+        if mode not in ["standard", "logo", "world"]:
+            raise TurtleGraphicsError("No turtle-graphics-mode %s" % mode)
+        self._mode = mode
+        if mode in ["standard", "logo"]:
+            self._setscrollregion(-self.canvwidth//2, -self.canvheight//2,
+                                       self.canvwidth//2, self.canvheight//2)
+            self.xscale = self.yscale = 1.0
+        self.reset()
 
-    def end_fill(self):
-        """ Called after drawing a shape to be filled.
+    def setworldcoordinates(self, llx, lly, urx, ury):
+        """Set up a user defined coordinate-system.
 
-        Example:
-        >>> turtle.begin_fill()
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.left(90)
-        >>> turtle.forward(100)
-        >>> turtle.end_fill()
+        Arguments:
+        llx -- a number, x-coordinate of lower left corner of canvas
+        lly -- a number, y-coordinate of lower left corner of canvas
+        urx -- a number, x-coordinate of upper right corner of canvas
+        ury -- a number, y-coordinate of upper right corner of canvas
+
+        Set up user coodinat-system and switch to mode 'world' if necessary.
+        This performs a screen.reset. If mode 'world' is already active,
+        all drawings are redrawn according to the new coordinates.
+
+        But ATTENTION: in user-defined coordinatesystems angles may appear
+        distorted. (see Screen.mode())
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.setworldcoordinates(-10,-0.5,50,1.5)
+        >>> for _ in range(36):
+                left(10)
+                forward(0.5)
         """
-        self.fill(0)
+        if self.mode() != "world":
+            self.mode("world")
+        xspan = float(urx - llx)
+        yspan = float(ury - lly)
+        wx, wy = self._window_size()
+        self.screensize(wx-20, wy-20)
+        oldxscale, oldyscale = self.xscale, self.yscale
+        self.xscale = self.canvwidth / xspan
+        self.yscale = self.canvheight / yspan
+        srx1 = llx * self.xscale
+        sry1 = -ury * self.yscale
+        srx2 = self.canvwidth + srx1
+        sry2 = self.canvheight + sry1
+        self._setscrollregion(srx1, sry1, srx2, sry2)
+        self._rescale(self.xscale/oldxscale, self.yscale/oldyscale)
+        self.update()
 
-    def circle(self, radius, extent = None):
-        """ Draw a circle with given radius.
-        The center is radius units left of the turtle; extent
-        determines which part of the circle is drawn. If not given,
-        the entire circle is drawn.
+    def register_shape(self, name, shape=None):
+        """Adds a turtle shape to TurtleScreen's shapelist.
 
-        If extent is not a full circle, one endpoint of the arc is the
-        current pen position. The arc is drawn in a counter clockwise
-        direction if radius is positive, otherwise in a clockwise
-        direction. In the process, the direction of the turtle is
-        changed by the amount of the extent.
+        Arguments:
+        (1) name is the name of a gif-file and shape is None.
+            Installs the corresponding image shape.
+            !! Image-shapes DO NOT rotate when turning the turtle,
+            !! so they do not display the heading of the turtle!
+        (2) name is an arbitrary string and shape is a tuple
+            of pairs of coordinates. Installs the corresponding
+            polygon shape
+        (3) name is an arbitrary string and shape is a
+            (compound) Shape object. Installs the corresponding
+            compound shape.
+        To use a shape, you have to issue the command shape(shapename).
 
-        >>> turtle.circle(50)
-        >>> turtle.circle(120, 180)  # half a circle
+        call: register_shape("turtle.gif")
+        --or: register_shape("tri", ((0,0), (10,10), (-10,10)))
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.register_shape("triangle", ((5,-3),(0,5),(-5,-3)))
+
         """
-        if extent is None:
-            extent = self._fullcircle
-        frac = abs(extent)/self._fullcircle
-        steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
-        w = 1.0 * extent / steps
-        w2 = 0.5 * w
-        l = 2.0 * radius * sin(w2*self._invradian)
-        if radius < 0:
-            l, w, w2 = -l, -w, -w2
-        self.left(w2)
-        for i in range(steps):
-            self.forward(l)
-            self.left(w)
-        self.right(w2)
+        if shape is None:
+            # image
+            if name.lower().endswith(".gif"):
+                shape = Shape("image", self._image(name))
+            else:
+                raise TurtleGraphicsError("Bad arguments for register_shape.\n"
+                                          + "Use  help(register_shape)" )
+        elif isinstance(shape, tuple):
+            shape = Shape("polygon", shape)
+        ## else shape assumed to be Shape-instance
+        self._shapes[name] = shape
+        # print "shape added:" , self._shapes
 
-    def heading(self):
-        """ Return the turtle's current heading.
+    def _colorstr(self, color):
+        """Return color string corresponding to args.
 
-        Example:
-        >>> turtle.heading()
-        67.0
+        Argument may be a string or a tuple of three
+        numbers corresponding to actual colormode,
+        i.e. in the range 0<=n<=colormode.
+
+        If the argument doesn't represent a color,
+        an error is raised.
         """
-        return self._angle
+        if len(color) == 1:
+            color = color[0]
+        if isinstance(color, str):
+            if self._iscolorstring(color) or color == "":
+                return color
+            else:
+                raise TurtleGraphicsError("bad color string: %s" % str(color))
+        try:
+            r, g, b = color
+        except:
+            raise TurtleGraphicsError("bad color arguments: %s" % str(color))
+        if self._colormode == 1.0:
+            r, g, b = [round(255.0*x) for x in (r, g, b)]
+        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+            raise TurtleGraphicsError("bad color sequence: %s" % str(color))
+        return "#%02x%02x%02x" % (r, g, b)
 
-    def setheading(self, angle):
-        """ Set the turtle facing the given angle.
+    def _color(self, cstr):
+        if not cstr.startswith("#"):
+            return cstr
+        if len(cstr) == 7:
+            cl = [int(cstr[i:i+2], 16) for i in (1, 3, 5)]
+        elif len(cstr) == 4:
+            cl = [16*int(cstr[h], 16) for h in cstr[1:]]
+        else:
+            raise TurtleGraphicsError("bad colorstring: %s" % cstr)
+        return tuple([c * self._colormode/255 for c in cl])
 
-        Here are some common directions in degrees:
+    def colormode(self, cmode=None):
+        """Return the colormode or set it to 1.0 or 255.
 
-           0 - east
-          90 - north
-         180 - west
-         270 - south
+        Optional argument:
+        cmode -- one of the values 1.0 or 255
 
-        Example:
-        >>> turtle.setheading(90)
-        >>> turtle.heading()
-        90
-        >>> turtle.setheading(128)
-        >>> turtle.heading()
-        128
+        r, g, b values of colortriples have to be in range 0..cmode.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.colormode()
+        1.0
+        >>> screen.colormode(255)
+        >>> turtle.pencolor(240,160,80)
         """
-        self._angle = angle
-        self._draw_turtle()
+        if cmode is None:
+            return self._colormode
+        if cmode == 1.0:
+            self._colormode = float(cmode)
+        elif cmode == 255:
+            self._colormode = int(cmode)
+
+    def reset(self):
+        """Reset all Turtles on the Screen to their initial state.
+
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.reset()
+        """
+        for turtle in self._turtles:
+            turtle._setmode(self._mode)
+            turtle.reset()
+
+    def turtles(self):
+        """Return the list of turtles on the screen.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.turtles()
+        [<turtle.Turtle object at 0x00E11FB0>]
+        """
+        return self._turtles
+
+    def bgcolor(self, *args):
+        """Set or return backgroundcolor of the TurtleScreen.
+
+        Arguments (if given): a color string or three numbers
+        in the range 0..colormode or a 3-tuple of such numbers.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bgcolor("orange")
+        >>> screen.bgcolor()
+        'orange'
+        >>> screen.bgcolor(0.5,0,0.5)
+        >>> screen.bgcolor()
+        '#800080'
+        """
+        if args:
+            color = self._colorstr(args)
+        else:
+            color = None
+        color = self._bgcolor(color)
+        if color is not None:
+            color = self._color(color)
+        return color
+
+    def tracer(self, n=None, delay=None):
+        """Turns turtle animation on/off and set delay for update drawings.
+
+        Optional arguments:
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second arguments sets delay value (see RawTurtle.delay())
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.tracer(8, 25)
+        >>> dist = 2
+        >>> for i in range(200):
+                fd(dist)
+                rt(90)
+                dist += 2
+        """
+        if n is None:
+            return self._tracing
+        self._tracing = int(n)
+        self._updatecounter = 0
+        if delay is not None:
+            self._delayvalue = int(delay)
+        if self._tracing:
+            self.update()
+
+    def delay(self, delay=None):
+        """ Return or set the drawing delay in milliseconds.
+
+        Optional argument:
+        delay -- positive integer
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.delay(15)
+        >>> screen.delay()
+        15
+        """
+        if delay is None:
+            return self._delayvalue
+        self._delayvalue = int(delay)
+
+    def _incrementudc(self):
+        "Increment upadate counter."""
+        if not TurtleScreen._RUNNING:
+            TurtleScreen._RUNNNING = True
+            raise Terminator
+        if self._tracing > 0:
+            self._updatecounter += 1
+            self._updatecounter %= self._tracing
+
+    def update(self):
+        """Perform a TurtleScreen update.
+        """
+        for t in self.turtles():
+            t._update_data()
+            t._drawturtle()
+        self._update()
 
     def window_width(self):
-        """ Returns the width of the turtle window.
+        """ Return the width of the turtle window.
 
-        Example:
-        >>> turtle.window_width()
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_width()
         640
         """
-        width = self._canvas.winfo_width()
-        if width <= 1:  # the window isn't managed by a geometry manager
-            width = self._canvas['width']
-        return width
+        return self._window_size()[0]
 
     def window_height(self):
         """ Return the height of the turtle window.
 
-        Example:
-        >>> turtle.window_height()
-        768
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.window_height()
+        480
         """
-        height = self._canvas.winfo_height()
-        if height <= 1: # the window isn't managed by a geometry manager
-            height = self._canvas['height']
-        return height
+        return self._window_size()[1]
 
-    def position(self):
-        """ Return the current (x, y) location of the turtle.
+    def getcanvas(self):
+        """Return the Canvas of this TurtleScreen.
 
-        Example:
-        >>> turtle.position()
-        [0.0, 240.0]
+        No argument.
+
+        Example (for a Screen instance named screen):
+        >>> cv = screen.getcanvas()
+        >>> cv
+        <turtle.ScrolledCanvas instance at 0x010742D8>
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        return [x1-x0, -y1+y0]
+        return self.cv
 
-    def setx(self, xpos):
-        """ Set the turtle's x coordinate to be xpos.
+    def getshapes(self):
+        """Return a list of names of all currently available turtle shapes.
 
-        Example:
+        No argument.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.getshapes()
+        ['arrow', 'blank', 'circle', ... , 'turtle']
+        """
+        return sorted(self._shapes.keys())
+
+    def onclick(self, fun, btn=1, add=None):
+        """Bind fun to mouse-click event on canvas.
+
+        Arguments:
+        fun -- a function with two arguments, the coordinates of the
+               clicked point on the canvas.
+        num -- the number of the mouse-button, defaults to 1
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle):
+
+        >>> screen.onclick(turtle.goto)
+
+        ### Subsequently clicking into the TurtleScreen will
+        ### make the turtle move to the clicked point.
+        >>> screen.onclick(None)
+
+        ### event-binding will be removed
+        """
+        self._onscreenclick(fun, btn, add)
+
+    def onkey(self, fun, key):
+        """Bind fun to key-release event of key.
+
+        Arguments:
+        fun -- a function with no arguments
+        key -- a string: key (e.g. "a") or key-symbol (e.g. "space")
+
+        In order ro be able to register key-events, TurtleScreen
+        must have focus. (See method listen.)
+
+        Example (for a TurtleScreen instance named screen
+        and a Turtle instance named turtle):
+
+        >>> def f():
+                fd(50)
+                lt(60)
+
+
+        >>> screen.onkey(f, "Up")
+        >>> screen.listen()
+
+        ### Subsequently the turtle can be moved by
+        ### repeatedly pressing the up-arrow key,
+        ### consequently drawing a hexagon
+        """
+        if fun == None:
+            self._keys.remove(key)
+        elif key not in self._keys:
+            self._keys.append(key)
+        self._onkey(fun, key)
+
+    def listen(self, xdummy=None, ydummy=None):
+        """Set focus on TurtleScreen (in order to collect key-events)
+
+        No arguments.
+        Dummy arguments are provided in order
+        to be able to pass listen to the onclick method.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.listen()
+        """
+        self._listen()
+
+    def ontimer(self, fun, t=0):
+        """Install a timer, which calls fun after t milliseconds.
+
+        Arguments:
+        fun -- a function with no arguments.
+        t -- a number >= 0
+
+        Example (for a TurtleScreen instance named screen):
+
+        >>> running = True
+        >>> def f():
+                if running:
+                        fd(50)
+                        lt(60)
+                        screen.ontimer(f, 250)
+
+        >>> f()   ### makes the turtle marching around
+        >>> running = False
+        """
+        self._ontimer(fun, t)
+
+    def bgpic(self, picname=None):
+        """Set background image or return name of current backgroundimage.
+
+        Optional argument:
+        picname -- a string, name of a gif-file or "nopic".
+
+        If picname is a filename, set the corresponing image as background.
+        If picname is "nopic", delete backgroundimage, if present.
+        If picname is None, return the filename of the current backgroundimage.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bgpic()
+        'nopic'
+        >>> screen.bgpic("landscape.gif")
+        >>> screen.bgpic()
+        'landscape.gif'
+        """
+        if picname is None:
+            return self._bgpicname
+        if picname not in self._bgpics:
+            self._bgpics[picname] = self._image(picname)
+        self._setbgpic(self._bgpic, self._bgpics[picname])
+        self._bgpicname = picname
+
+    def screensize(self, canvwidth=None, canvheight=None, bg=None):
+        """Resize the canvas, the turtles are drawing on.
+
+        Optional arguments:
+        canvwidth -- positive integer, new width of canvas in pixels
+        canvheight --  positive integer, new height of canvas in pixels
+        bg -- colorstring or color-tupel, new backgroundcolor
+        If no arguments are given, return current (canvaswidth, canvasheight)
+
+        Do not alter the drawing window. To observe hidden parts of
+        the canvas use the scrollbars. (Can make visible those parts
+        of a drawing, which were outside the canvas before!)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.screensize(2000,1500)
+            ### e. g. to search for an erroneously escaped turtle ;-)
+        """
+        return self._resize(canvwidth, canvheight, bg)
+
+    onscreenclick = onclick
+    resetscreen = reset
+    clearscreen = clear
+    addshape = register_shape
+
+class TNavigator(object):
+    """Navigation part of the RawTurtle.
+    Implements methods for turtle movement.
+    """
+    START_ORIENTATION = {
+        "standard": Vec2D(1.0, 0.0),
+        "world"   : Vec2D(1.0, 0.0),
+        "logo"    : Vec2D(0.0, 1.0)  }
+    DEFAULT_MODE = "standard"
+    DEFAULT_ANGLEOFFSET = 0
+    DEFAULT_ANGLEORIENT = 1
+
+    def __init__(self, mode=DEFAULT_MODE):
+        self._angleOffset = self.DEFAULT_ANGLEOFFSET
+        self._angleOrient = self.DEFAULT_ANGLEORIENT
+        self._mode = mode
+        self.undobuffer = None
+        self.degrees()
+        self._mode = None
+        self._setmode(mode)
+        TNavigator.reset(self)
+
+    def reset(self):
+        """reset turtle to its initial values
+
+        Will be overwritten by parent class
+        """
+        self._position = Vec2D(0.0, 0.0)
+        self._orient =  TNavigator.START_ORIENTATION[self._mode]
+
+    def _setmode(self, mode=None):
+        """Set turtle-mode to 'standard', 'world' or 'logo'.
+        """
+        if mode == None:
+            return self._mode
+        if mode not in ["standard", "logo", "world"]:
+            return
+        self._mode = mode
+        if mode in ["standard", "world"]:
+            self._angleOffset = 0
+            self._angleOrient = 1
+        else: # mode == "logo":
+            self._angleOffset = self._fullcircle/4.
+            self._angleOrient = -1
+
+    def _setDegreesPerAU(self, fullcircle):
+        """Helper function for degrees() and radians()"""
+        self._fullcircle = fullcircle
+        self._degreesPerAU = 360/fullcircle
+        if self._mode == "standard":
+            self._angleOffset = 0
+        else:
+            self._angleOffset = fullcircle/4.
+
+    def degrees(self, fullcircle=360.0):
+        """ Set angle measurement units to degrees.
+
+        Optional argument:
+        fullcircle -  a number
+
+        Set angle measurement units, i. e. set number
+        of 'degrees' for a full circle. Dafault value is
+        360 degrees.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.left(90)
+        >>> turtle.heading()
+        90
+        >>> turtle.degrees(400.0)  # angle measurement in gon
+        >>> turtle.heading()
+        100
+
+        """
+        self._setDegreesPerAU(fullcircle)
+
+    def radians(self):
+        """ Set the angle measurement units to radians.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        90
+        >>> turtle.radians()
+        >>> turtle.heading()
+        1.5707963267948966
+        """
+        self._setDegreesPerAU(2*math.pi)
+
+    def _go(self, distance):
+        """move turtle forward by specified distance"""
+        ende = self._position + self._orient * distance
+        self._goto(ende)
+
+    def _rotate(self, angle):
+        """Turn turtle counterclockwise by specified angle if angle > 0."""
+        angle *= self._degreesPerAU
+        self._orient = self._orient.rotate(angle)
+
+    def _goto(self, end):
+        """move turtle to position end."""
+        self._position = end
+
+    def forward(self, distance):
+        """Move the turtle forward by the specified distance.
+
+        Aliases: forward | fd
+
+        Argument:
+        distance -- a number (integer or float)
+
+        Move the turtle forward by the specified distance, in the direction
+        the turtle is headed.
+
+        Example (for a Turtle instance named turtle):
         >>> turtle.position()
-        [10.0, 240.0]
+        (0.00, 0.00)
+        >>> turtle.forward(25)
+        >>> turtle.position()
+        (25.00,0.00)
+        >>> turtle.forward(-75)
+        >>> turtle.position()
+        (-50.00,0.00)
+        """
+        self._go(distance)
+
+    def back(self, distance):
+        """Move the turtle backward by distance.
+
+        Aliases: back | backward | bk
+
+        Argument:
+        distance -- a number
+
+        Move the turtle backward by distance ,opposite to the direction the
+        turtle is headed. Do not change the turtle's heading.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 0.00)
+        >>> turtle.backward(30)
+        >>> turtle.position()
+        (-30.00, 0.00)
+        """
+        self._go(-distance)
+
+    def right(self, angle):
+        """Turn turtle right by angle units.
+
+        Aliases: right | rt
+
+        Argument:
+        angle -- a number (integer or float)
+
+        Turn turtle right by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        22.0
+        >>> turtle.right(45)
+        >>> turtle.heading()
+        337.0
+        """
+        self._rotate(-angle)
+
+    def left(self, angle):
+        """Turn turtle left by angle units.
+
+        Aliases: left | lt
+
+        Argument:
+        angle -- a number (integer or float)
+
+        Turn turtle left by angle units. (Units are by default degrees,
+        but can be set via the degrees() and radians() functions.)
+        Angle orientation depends on mode. (See this.)
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.heading()
+        22.0
+        >>> turtle.left(45)
+        >>> turtle.heading()
+        67.0
+        """
+        self._rotate(angle)
+
+    def pos(self):
+        """Return the turtle's current location (x,y), as a Vec2D-vector.
+
+        Aliases: pos | position
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (0.00, 240.00)
+        """
+        return self._position
+
+    def xcor(self):
+        """ Return the turtle's x coordinate.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> reset()
+        >>> turtle.left(60)
+        >>> turtle.forward(100)
+        >>> print turtle.xcor()
+        50.0
+        """
+        return self._position[0]
+
+    def ycor(self):
+        """ Return the turtle's y coordinate
+        ---
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> reset()
+        >>> turtle.left(60)
+        >>> turtle.forward(100)
+        >>> print turtle.ycor()
+        86.6025403784
+        """
+        return self._position[1]
+
+
+    def goto(self, x, y=None):
+        """Move turtle to an absolute position.
+
+        Aliases: setpos | setposition | goto:
+
+        Arguments:
+        x -- a number      or     a pair/vector of numbers
+        y -- a number             None
+
+        call: goto(x, y)         # two coordinates
+        --or: goto((x, y))       # a pair (tuple) of coordinates
+        --or: goto(vec)          # e.g. as returned by pos()
+
+        Move turtle to an absolute position. If the pen is down,
+        a line will be drawn. The turtle's orientation does not change.
+
+        Example (for a Turtle instance named turtle):
+        >>> tp = turtle.pos()
+        >>> tp
+        (0.00, 0.00)
+        >>> turtle.setpos(60,30)
+        >>> turtle.pos()
+        (60.00,30.00)
+        >>> turtle.setpos((20,80))
+        >>> turtle.pos()
+        (20.00,80.00)
+        >>> turtle.setpos(tp)
+        >>> turtle.pos()
+        (0.00,0.00)
+        """
+        if y is None:
+            self._goto(Vec2D(*x))
+        else:
+            self._goto(Vec2D(x, y))
+
+    def home(self):
+        """Move turtle to the origin - coordinates (0,0).
+
+        No arguments.
+
+        Move turtle to the origin - coordinates (0,0) and set it's
+        heading to it's start-orientation (which depends on mode).
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.home()
+        """
+        self.goto(0, 0)
+        self.setheading(0)
+
+    def setx(self, x):
+        """Set the turtle's first coordinate to x
+
+        Argument:
+        x -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, leave second coordinate
+        unchanged.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00, 240.00)
         >>> turtle.setx(10)
         >>> turtle.position()
-        [10.0, 240.0]
+        (10.00, 240.00)
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x0+xpos, y1)
+        self._goto(Vec2D(x, self._position[1]))
 
-    def sety(self, ypos):
-        """ Set the turtle's y coordinate to be ypos.
+    def sety(self, y):
+        """Set the turtle's second coordinate to y
 
-        Example:
+        Argument:
+        y -- a number (integer or float)
+
+        Set the turtle's first coordinate to x, second coordinate remains
+        unchanged.
+
+        Example (for a Turtle instance named turtle):
         >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.sety(-22)
+        (0.00, 40.00)
+        >>> turtle.sety(-10)
         >>> turtle.position()
-        [0.0, -22.0]
+        (0.00, -10.00)
         """
-        x0, y0 = self._origin
-        x1, y1 = self._position
-        self._goto(x1, y0-ypos)
+        self._goto(Vec2D(self._position[0], y))
 
-    def towards(self, *args):
-        """Returs the angle, which corresponds to the line
-        from turtle-position to point (x,y).
+    def distance(self, x, y=None):
+        """Return the distance from the turtle to (x,y) in turtle step units.
 
-        Argument can be two coordinates or one pair of coordinates
-        or a RawPen/Pen instance.
+        Arguments:
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None
 
-        Example:
-        >>> turtle.position()
-        [10.0, 10.0]
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (0.00, 0.00)
+        >>> turtle.distance(30,40)
+        50.0
+        >>> pen = Turtle()
+        >>> pen.forward(77)
+        >>> turtle.distance(pen)
+        77.0
+        """
+        if y is not None:
+            pos = Vec2D(x, y)
+        if isinstance(x, Vec2D):
+            pos = x
+        elif isinstance(x, tuple):
+            pos = Vec2D(*x)
+        elif isinstance(x, TNavigator):
+            pos = x._position
+        return abs(pos - self._position)
+
+    def towards(self, x, y=None):
+        """Return the angle of the line from the turtle's position to (x, y).
+
+        Arguments:
+        x -- a number   or  a pair/vector of numbers   or   a turtle instance
+        y -- a number       None                            None
+
+        call: distance(x, y)         # two coordinates
+        --or: distance((x, y))       # a pair (tuple) of coordinates
+        --or: distance(vec)          # e.g. as returned by pos()
+        --or: distance(mypen)        # where mypen is another turtle
+
+        Return the angle, between the line from turtle-position to position
+        specified by x, y and the turtle's start orientation. (Depends on
+        modes - "standard" or "logo")
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pos()
+        (10.00, 10.00)
         >>> turtle.towards(0,0)
         225.0
         """
-        if len(args) == 2:
-            x, y = args
+        if y is not None:
+            pos = Vec2D(x, y)
+        if isinstance(x, Vec2D):
+            pos = x
+        elif isinstance(x, tuple):
+            pos = Vec2D(*x)
+        elif isinstance(x, TNavigator):
+            pos = x._position
+        x, y = pos - self._position
+        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+        result /= self._degreesPerAU
+        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+    def heading(self):
+        """ Return the turtle's current heading.
+
+        No arguments.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.left(67)
+        >>> turtle.heading()
+        67.0
+        """
+        x, y = self._orient
+        result = round(math.atan2(y, x)*180.0/math.pi, 10) % 360.0
+        result /= self._degreesPerAU
+        return (self._angleOffset + self._angleOrient*result) % self._fullcircle
+
+    def setheading(self, to_angle):
+        """Set the orientation of the turtle to to_angle.
+
+        Aliases:  setheading | seth
+
+        Argument:
+        to_angle -- a number (integer or float)
+
+        Set the orientation of the turtle to to_angle.
+        Here are some common directions in degrees:
+
+         standard - mode:          logo-mode:
+        -------------------|--------------------
+           0 - east                0 - north
+          90 - north              90 - east
+         180 - west              180 - south
+         270 - south             270 - west
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.setheading(90)
+        >>> turtle.heading()
+        90
+        """
+        angle = (to_angle - self.heading())*self._angleOrient
+        full = self._fullcircle
+        angle = (angle+full/2.)%full - full/2.
+        self._rotate(angle)
+
+    def circle(self, radius, extent = None, steps = None):
+        """ Draw a circle with given radius.
+
+        Arguments:
+        radius -- a number
+        extent (optional) -- a number
+        steps (optional) -- an integer
+
+        Draw a circle with given radius. The center is radius units left
+        of the turtle; extent - an angle - determines which part of the
+        circle is drawn. If extent is not given, draw the entire circle.
+        If extent is not a full circle, one endpoint of the arc is the
+        current pen position. Draw the arc in counterclockwise direction
+        if radius is positive, otherwise in clockwise direction. Finally
+        the direction of the turtle is changed by the amount of extent.
+
+        As the circle is approximated by an inscribed regular polygon,
+        steps determines the number of steps to use. If not given,
+        it will be calculated automatically. Maybe used to draw regular
+        polygons.
+
+        call: circle(radius)                  # full circle
+        --or: circle(radius, extent)          # arc
+        --or: circle(radius, extent, steps)
+        --or: circle(radius, steps=6)         # 6-sided polygon
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.circle(50)
+        >>> turtle.circle(120, 180)  # semicircle
+        """
+        if self.undobuffer:
+            self.undobuffer.push(["seq"])
+            self.undobuffer.cumulate = True
+        speed = self.speed()
+        if extent is None:
+            extent = self._fullcircle
+        if steps is None:
+            frac = abs(extent)/self._fullcircle
+            steps = 1+int(min(11+abs(radius)/6.0, 59.0)*frac)
+        w = 1.0 * extent / steps
+        w2 = 0.5 * w
+        l = 2.0 * radius * math.sin(w2*math.pi/180.0*self._degreesPerAU)
+        if radius < 0:
+            l, w, w2 = -l, -w, -w2
+        tr = self._tracer()
+        dl = self._delay()
+        if speed == 0:
+            self._tracer(0, 0)
         else:
-            arg = args[0]
-            if isinstance(arg, RawPen):
-                x, y = arg.position()
-            else:
-                x, y = arg
-        x0, y0 = self.position()
-        dx = x - x0
-        dy = y - y0
-        return (atan2(dy,dx) / self._invradian) % self._fullcircle
+            self.speed(0)
+        self._rotate(w2)
+        for i in range(steps):
+            self.speed(speed)
+            self._go(l)
+            self.speed(0)
+            self._rotate(w)
+        self._rotate(-w2)
+        if speed == 0:
+            self._tracer(tr, dl)
+        self.speed(speed)
+        if self.undobuffer:
+            self.undobuffer.cumulate = False
 
-    def goto(self, *args):
-        """ Go to the given point.
+## three dummy methods to be implemented by child class:
 
-        If the pen is down, then a line will be drawn. The turtle's
-        orientation does not change.
+    def speed(self, s=0):
+        """dummy method - to be overwritten by child class"""
+    def _tracer(self, a=None, b=None):
+        """dummy method - to be overwritten by child class"""
+    def _delay(self, n=None):
+        """dummy method - to be overwritten by child class"""
 
-        Two input formats are accepted:
+    fd = forward
+    bk = back
+    backward = back
+    rt = right
+    lt = left
+    position = pos
+    setpos = goto
+    setposition = goto
+    seth = setheading
 
-           goto(x, y)
-           go to point (x, y)
 
-           goto((x, y))
-           go to point (x, y)
+class TPen(object):
+    """Drawing part of the RawTurtle.
+    Implements drawing properties.
+    """
+    def __init__(self, resizemode=_CFG["resizemode"]):
+        self._resizemode = resizemode # or "user" or "noresize"
+        self.undobuffer = None
+        TPen._reset(self)
 
-        Example:
-        >>> turtle.position()
-        [0.0, 0.0]
-        >>> turtle.goto(50, -45)
-        >>> turtle.position()
-        [50.0, -45.0]
+    def _reset(self, pencolor=_CFG["pencolor"],
+                     fillcolor=_CFG["fillcolor"]):
+        self._pensize = 1
+        self._shown = True
+        self._pencolor = pencolor
+        self._fillcolor = fillcolor
+        self._drawing = True
+        self._speed = 3
+        self._stretchfactor = (1, 1)
+        self._tilt = 0
+        self._outlinewidth = 1
+        ### self.screen = None  # to override by child class
+
+    def resizemode(self, rmode=None):
+        """Set resizemode to one of the values: "auto", "user", "noresize".
+
+        (Optional) Argument:
+        rmode -- one of the strings "auto", "user", "noresize"
+
+        Different resizemodes have the following effects:
+          - "auto" adapts the appearance of the turtle
+                   corresponding to the value of pensize.
+          - "user" adapts the appearance of the turtle according to the
+                   values of stretchfactor and outlinewidth (outline),
+                   which are set by shapesize()
+          - "noresize" no adaption of the turtle's appearance takes place.
+        If no argument is given, return current resizemode.
+        resizemode("user") is called by a call of shapesize with arguments.
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.resizemode("noresize")
+        >>> turtle.resizemode()
+        'noresize'
         """
-        if len(args) == 1:
-            try:
-                x, y = args[0]
-            except:
-                raise Error("bad point argument: %r" % (args[0],))
-        else:
-            try:
-                x, y = args
-            except:
-                raise Error("bad coordinates: %r" % (args[0],))
-        x0, y0 = self._origin
-        self._goto(x0+x, y0-y)
+        if rmode is None:
+            return self._resizemode
+        rmode = rmode.lower()
+        if rmode in ["auto", "user", "noresize"]:
+            self.pen(resizemode=rmode)
 
-    def _goto(self, x1, y1):
-        x0, y0 = self._position
-        self._position = (float(x1), float(y1))
-        if self._filling:
-            self._path.append(self._position)
-        if self._drawing:
-            if self._tracing:
-                dx = float(x1 - x0)
-                dy = float(y1 - y0)
-                distance = hypot(dx, dy)
-                nhops = int(distance)
-                item = self._canvas.create_line(x0, y0, x0, y0,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-                try:
-                    for i in range(1, 1+nhops):
-                        x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
-                        self._canvas.coords(item, x0, y0, x, y)
-                        self._draw_turtle((x,y))
-                        self._canvas.update()
-                        self._canvas.after(self._delay)
-                    # in case nhops==0
-                    self._canvas.coords(item, x0, y0, x1, y1)
-                    self._canvas.itemconfigure(item, arrow="none")
-                except tkinter.TclError:
-                    # Probably the window was closed!
-                    return
-            else:
-                item = self._canvas.create_line(x0, y0, x1, y1,
-                                                width=self._width,
-                                                capstyle="round",
-                                                fill=self._color)
-            self._items.append(item)
-        self._draw_turtle()
+    def pensize(self, width=None):
+        """Set or return the line thickness.
 
-    def speed(self, speed):
-        """ Set the turtle's speed.
+        Aliases:  pensize | width
 
-        speed must one of these five strings:
+        Argument:
+        width -- positive number
 
-            'fastest' is a 0 ms delay
-            'fast' is a 5 ms delay
-            'normal' is a 10 ms delay
-            'slow' is a 15 ms delay
-            'slowest' is a 20 ms delay
+        Set the line thickness to width or return it. If resizemode is set
+        to "auto" and turtleshape is a polygon, that polygon is drawn with
+        the same line thickness. If no argument is given, current pensize
+        is returned.
 
-         Example:
-         >>> turtle.speed('slow')
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pensize()
+        1
+        turtle.pensize(10)   # from here on lines of width 10 are drawn
         """
-        try:
-            speed = speed.strip().lower()
-            self._delay = speeds.index(speed) * 5
-        except:
-            raise ValueError("%r is not a valid speed. speed must be "
-                             "one of %s" % (speed, speeds))
+        if width is None:
+            return self._pensize
+        self.pen(pensize=width)
 
 
-    def delay(self, delay):
-        """ Set the drawing delay in milliseconds.
+    def penup(self):
+        """Pull the pen up -- no drawing when moving.
 
-        This is intended to allow finer control of the drawing speed
-        than the speed() method
+        Aliases: penup | pu | up
 
-        Example:
-        >>> turtle.delay(15)
+        No argument
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
         """
-        if int(delay) < 0:
-            raise ValueError("delay must be greater than or equal to 0")
-        self._delay = int(delay)
-
-    def _draw_turtle(self, position=[]):
-        if not self._tracing:
-            self._canvas.update()
+        if not self._drawing:
             return
-        if position == []:
-            position = self._position
-        x,y = position
-        distance = 8
-        dx = distance * cos(self._angle*self._invradian)
-        dy = distance * sin(self._angle*self._invradian)
-        self._delete_turtle()
-        self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
-                                          width=self._width,
-                                          arrow="last",
-                                          capstyle="round",
-                                          fill=self._color)
-        self._canvas.update()
+        self.pen(pendown=False)
 
-    def _delete_turtle(self):
-        if self._arrow != 0:
-            self._canvas.delete(self._arrow)
-            self._arrow = 0
+    def pendown(self):
+        """Pull the pen down -- drawing when moving.
+
+        Aliases: pendown | pd | down
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pendown()
+        """
+        if self._drawing:
+            return
+        self.pen(pendown=True)
+
+    def isdown(self):
+        """Return True if pen is down, False if it's up.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.penup()
+        >>> turtle.isdown()
+        False
+        >>> turtle.pendown()
+        >>> turtle.isdown()
+        True
+        """
+        return self._drawing
+
+    def speed(self, speed=None):
+        """ Return or set the turtle's speed.
+
+        Optional argument:
+        speed -- an integer in the range 0..10 or a speedstring (see below)
+
+        Set the turtle's speed to an integer value in the range 0 .. 10.
+        If no argument is given: return current speed.
+
+        If input is a number greater than 10 or smaller than 0.5,
+        speed is set to 0.
+        Speedstrings  are mapped to speedvalues in the following way:
+            'fastest' :  0
+            'fast'    :  10
+            'normal'  :  6
+            'slow'    :  3
+            'slowest' :  1
+        speeds from 1 to 10 enforce increasingly faster animation of
+        line drawing and turtle turning.
+
+        Attention:
+        speed = 0 : *no* animation takes place. forward/back makes turtle jump
+        and likewise left/right make the turtle turn instantly.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.speed(3)
+        """
+        speeds = {'fastest':0, 'fast':10, 'normal':6, 'slow':3, 'slowest':1 }
+        if speed is None:
+            return self._speed
+        if speed in speeds:
+            speed = speeds[speed]
+        elif 0.5 < speed < 10.5:
+            speed = int(round(speed))
+        else:
+            speed = 0
+        self.pen(speed=speed)
+
+    def color(self, *args):
+        """Return or set the pencolor and fillcolor.
+
+        Arguments:
+        Several input formats are allowed.
+        They use 0, 1, 2, or 3 arguments as follows:
+
+        color()
+            Return the current pencolor and the current fillcolor
+            as a pair of color specification strings as are returned
+            by pencolor and fillcolor.
+        color(colorstring), color((r,g,b)), color(r,g,b)
+            inputs as in pencolor, set both, fillcolor and pencolor,
+            to the given value.
+        color(colorstring1, colorstring2),
+        color((r1,g1,b1), (r2,g2,b2))
+            equivalent to pencolor(colorstring1) and fillcolor(colorstring2)
+            and analogously, if the other input format is used.
+
+        If turtleshape is a polygon, outline and interior of that polygon
+        is drawn with the newly set colors.
+        For mor info see: pencolor, fillcolor
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color('red', 'green')
+        >>> turtle.color()
+        ('red', 'green')
+        >>> colormode(255)
+        >>> color((40, 80, 120), (160, 200, 240))
+        >>> color()
+        ('#285078', '#a0c8f0')
+        """
+        if args:
+            l = len(args)
+            if l == 1:
+                pcolor = fcolor = args[0]
+            elif l == 2:
+                pcolor, fcolor = args
+            elif l == 3:
+                pcolor = fcolor = args
+            pcolor = self._colorstr(pcolor)
+            fcolor = self._colorstr(fcolor)
+            self.pen(pencolor=pcolor, fillcolor=fcolor)
+        else:
+            return self._color(self._pencolor), self._color(self._fillcolor)
+
+    def pencolor(self, *args):
+        """ Return or set the pencolor.
+
+        Arguments:
+        Four input formats are allowed:
+          - pencolor()
+            Return the current pencolor as color specification string,
+            possibly in hex-number format (see example).
+            May be used as input to another color/pencolor/fillcolor call.
+          - pencolor(colorstring)
+            s is a Tk color specification string, such as "red" or "yellow"
+          - pencolor((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range 0..colormode,
+            where colormode is either 1.0 or 255
+          - pencolor(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range 0..colormode
+
+        If turtleshape is a polygon, the outline of that polygon is drawn
+        with the newly set pencolor.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.pencolor('brown')
+        >>> tup = (0.2, 0.8, 0.55)
+        >>> turtle.pencolor(tup)
+        >>> turtle.pencolor()
+        '#33cc8c'
+        """
+        if args:
+            color = self._colorstr(args)
+            if color == self._pencolor:
+                return
+            self.pen(pencolor=color)
+        else:
+            return self._color(self._pencolor)
+
+    def fillcolor(self, *args):
+        """ Return or set the fillcolor.
+
+        Arguments:
+        Four input formats are allowed:
+          - fillcolor()
+            Return the current fillcolor as color specification string,
+            possibly in hex-number format (see example).
+            May be used as input to another color/pencolor/fillcolor call.
+          - fillcolor(colorstring)
+            s is a Tk color specification string, such as "red" or "yellow"
+          - fillcolor((r, g, b))
+            *a tuple* of r, g, and b, which represent, an RGB color,
+            and each of r, g, and b are in the range 0..colormode,
+            where colormode is either 1.0 or 255
+          - fillcolor(r, g, b)
+            r, g, and b represent an RGB color, and each of r, g, and b
+            are in the range 0..colormode
+
+        If turtleshape is a polygon, the interior of that polygon is drawn
+        with the newly set fillcolor.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.fillcolor('violet')
+        >>> col = turtle.pencolor()
+        >>> turtle.fillcolor(col)
+        >>> turtle.fillcolor(0, .5, 0)
+        """
+        if args:
+            color = self._colorstr(args)
+            if color == self._fillcolor:
+                return
+            self.pen(fillcolor=color)
+        else:
+            return self._color(self._fillcolor)
+
+    def showturtle(self):
+        """Makes the turtle visible.
+
+        Aliases: showturtle | st
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        >>> turtle.showturtle()
+        """
+        self.pen(shown=True)
+
+    def hideturtle(self):
+        """Makes the turtle invisible.
+
+        Aliases: hideturtle | ht
+
+        No argument.
+
+        It's a good idea to do this while you're in the
+        middle of a complicated drawing, because hiding
+        the turtle speeds up the drawing observably.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        """
+        self.pen(shown=False)
+
+    def isvisible(self):
+        """Return True if the Turtle is shown, False if it's hidden.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.hideturtle()
+        >>> print turtle.isvisible():
+        False
+        """
+        return self._shown
+
+    def pen(self, pen=None, **pendict):
+        """Return or set the pen's attributes.
+
+        Arguments:
+            pen -- a dictionary with some or all of the below listed keys.
+            **pendict -- one or more keyword-arguments with the below
+                         listed keys as keywords.
+
+        Return or set the pen's attributes in a 'pen-dictionary'
+        with the following key/value pairs:
+           "shown"      :   True/False
+           "pendown"    :   True/False
+           "pencolor"   :   color-string or color-tuple
+           "fillcolor"  :   color-string or color-tuple
+           "pensize"    :   positive number
+           "speed"      :   number in range 0..10
+           "resizemode" :   "auto" or "user" or "noresize"
+           "stretchfactor": (positive number, positive number)
+           "outline"    :   positive number
+           "tilt"       :   number
+
+        This dicionary can be used as argument for a subsequent
+        pen()-call to restore the former pen-state. Moreover one
+        or more of these attributes can be provided as keyword-arguments.
+        This can be used to set several pen attributes in one statement.
 
 
-_root = None
-_canvas = None
-_pen = None
-_width = 0.50                  # 50% of window width
-_height = 0.75                 # 75% of window height
-_startx = None
-_starty = None
-_title = "Turtle Graphics"     # default title
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.pen(fillcolor="black", pencolor="red", pensize=10)
+        >>> turtle.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'red', 'pendown': True, 'fillcolor': 'black',
+        'stretchfactor': (1,1), 'speed': 3}
+        >>> penstate=turtle.pen()
+        >>> turtle.color("yellow","")
+        >>> turtle.penup()
+        >>> turtle.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'yellow', 'pendown': False, 'fillcolor': '',
+        'stretchfactor': (1,1), 'speed': 3}
+        >>> p.pen(penstate, fillcolor="green")
+        >>> p.pen()
+        {'pensize': 10, 'shown': True, 'resizemode': 'auto', 'outline': 1,
+        'pencolor': 'red', 'pendown': True, 'fillcolor': 'green',
+        'stretchfactor': (1,1), 'speed': 3}
+        """
+        _pd =  {"shown"         : self._shown,
+                "pendown"       : self._drawing,
+                "pencolor"      : self._pencolor,
+                "fillcolor"     : self._fillcolor,
+                "pensize"       : self._pensize,
+                "speed"         : self._speed,
+                "resizemode"    : self._resizemode,
+                "stretchfactor" : self._stretchfactor,
+                "outline"       : self._outlinewidth,
+                "tilt"          : self._tilt
+               }
 
-class Pen(RawPen):
+        if not (pen or pendict):
+            return _pd
+
+        if isinstance(pen, dict):
+            p = pen
+        else:
+            p = {}
+        p.update(pendict)
+
+        _p_buf = {}
+        for key in p:
+            _p_buf[key] = _pd[key]
+
+        if self.undobuffer:
+            self.undobuffer.push(("pen", _p_buf))
+
+        newLine = False
+        if "pendown" in p:
+            if self._drawing != p["pendown"]:
+                newLine = True
+        if "pencolor" in p:
+            if isinstance(p["pencolor"], tuple):
+                p["pencolor"] = self._colorstr((p["pencolor"],))
+            if self._pencolor != p["pencolor"]:
+                newLine = True
+        if "pensize" in p:
+            if self._pensize != p["pensize"]:
+                newLine = True
+        if newLine:
+            self._newLine()
+        if "pendown" in p:
+            self._drawing = p["pendown"]
+        if "pencolor" in p:
+            self._pencolor = p["pencolor"]
+        if "pensize" in p:
+            self._pensize = p["pensize"]
+        if "fillcolor" in p:
+            if isinstance(p["fillcolor"], tuple):
+                p["fillcolor"] = self._colorstr((p["fillcolor"],))
+            self._fillcolor = p["fillcolor"]
+        if "speed" in p:
+            self._speed = p["speed"]
+        if "resizemode" in p:
+            self._resizemode = p["resizemode"]
+        if "stretchfactor" in p:
+            sf = p["stretchfactor"]
+            if isinstance(sf, (int, float)):
+                sf = (sf, sf)
+            self._stretchfactor = sf
+        if "outline" in p:
+            self._outlinewidth = p["outline"]
+        if "shown" in p:
+            self._shown = p["shown"]
+        if "tilt" in p:
+            self._tilt = p["tilt"]
+        self._update()
+
+## three dummy methods to be implemented by child class:
+
+    def _newLine(self, usePos = True):
+        """dummy method - to be overwritten by child class"""
+    def _update(self, count=True, forced=False):
+        """dummy method - to be overwritten by child class"""
+    def _color(self, args):
+        """dummy method - to be overwritten by child class"""
+    def _colorstr(self, args):
+        """dummy method - to be overwritten by child class"""
+
+    width = pensize
+    up = penup
+    pu = penup
+    pd = pendown
+    down = pendown
+    st = showturtle
+    ht = hideturtle
+
+
+class _TurtleImage(object):
+    """Helper class: Datatype to store Turtle attributes
+    """
+
+    def __init__(self, screen, shapeIndex):
+        self.screen = screen
+        self._type = None
+        self._setshape(shapeIndex)
+
+    def _setshape(self, shapeIndex):
+        screen = self.screen # RawTurtle.screens[self.screenIndex]
+        self.shapeIndex = shapeIndex
+        if self._type == "polygon" == screen._shapes[shapeIndex]._type:
+            return
+        if self._type == "image" == screen._shapes[shapeIndex]._type:
+            return
+        if self._type in ["image", "polygon"]:
+            screen._delete(self._item)
+        elif self._type == "compound":
+            for item in self._item:
+                screen._delete(item)
+        self._type = screen._shapes[shapeIndex]._type
+        if self._type == "polygon":
+            self._item = screen._createpoly()
+        elif self._type == "image":
+            self._item = screen._createimage(screen._shapes["blank"]._data)
+        elif self._type == "compound":
+            self._item = [screen._createpoly() for item in
+                                          screen._shapes[shapeIndex]._data]
+
+
+class RawTurtle(TPen, TNavigator):
+    """Animation part of the RawTurtle.
+    Puts RawTurtle upon a TurtleScreen and provides tools for
+    it's animation.
+    """
+    screens = []
+
+    def __init__(self, canvas=None,
+                 shape=_CFG["shape"],
+                 undobuffersize=_CFG["undobuffersize"],
+                 visible=_CFG["visible"]):
+        if isinstance(canvas, Screen):
+            self.screen = canvas
+        elif isinstance(canvas, TurtleScreen):
+            if canvas not in RawTurtle.screens:
+                RawTurtle.screens.append(canvas)
+            self.screen = canvas
+        elif isinstance(canvas, (ScrolledCanvas, Canvas)):
+            for screen in RawTurtle.screens:
+                if screen.cv == canvas:
+                    self.screen = screen
+                    break
+            else:
+                self.screen = TurtleScreen(canvas)
+                RawTurtle.screens.append(self.screen)
+        else:
+            raise TurtleGraphicsError("bad cavas argument %s" % canvas)
+
+        screen = self.screen
+        TNavigator.__init__(self, screen.mode())
+        TPen.__init__(self)
+        screen._turtles.append(self)
+        self.drawingLineItem = screen._createline()
+        self.turtle = _TurtleImage(screen, shape)
+        self._poly = None
+        self._creatingPoly = False
+        self._fillitem = self._fillpath = None
+        self._shown = visible
+        self._hidden_from_screen = False
+        self.currentLineItem = screen._createline()
+        self.currentLine = [self._position]
+        self.items = [self.currentLineItem]
+        self.stampItems = []
+        self._undobuffersize = undobuffersize
+        self.undobuffer = Tbuffer(undobuffersize)
+        self._update()
+
+    def reset(self):
+        """Delete the turtle's drawings and restore it's default values.
+
+        No argument.
+,
+        Delete the turtle's drawings from the screen, re-center the turtle
+        and set variables to the default values.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.position()
+        (0.00,-22.00)
+        >>> turtle.heading()
+        100.0
+        >>> turtle.reset()
+        >>> turtle.position()
+        (0.00,0.00)
+        >>> turtle.heading()
+        0.0
+        """
+        TNavigator.reset(self)
+        TPen._reset(self)
+        self._clear()
+        self._drawturtle()
+        self._update()
+
+    def setundobuffer(self, size):
+        """Set or disable undobuffer.
+
+        Argument:
+        size -- an integer or None
+
+        If size is an integer an empty undobuffer of given size is installed.
+        Size gives the maximum number of turtle-actions that can be undone
+        by the undo() function.
+        If size is None, no undobuffer is present.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.setundobuffer(42)
+        """
+        if size is None:
+            self.undobuffer = None
+        else:
+            self.undobuffer = Tbuffer(size)
+
+    def undobufferentries(self):
+        """Return count of entries in the undobuffer.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> while undobufferentries():
+                undo()
+        """
+        if self.undobuffer is None:
+            return 0
+        return self.undobuffer.nr_of_items()
+
+    def _clear(self):
+        """Delete all of pen's drawings"""
+        self._fillitem = self._fillpath = None
+        for item in self.items:
+            self.screen._delete(item)
+        self.currentLineItem = self.screen._createline()
+        self.currentLine = []
+        if self._drawing:
+            self.currentLine.append(self._position)
+        self.items = [self.currentLineItem]
+        self.clearstamps()
+        self.setundobuffer(self._undobuffersize)
+
+
+    def clear(self):
+        """Delete the turtle's drawings from the screen. Do not move turtle.
+
+        No arguments.
+
+        Delete the turtle's drawings from the screen. Do not move turtle.
+        State and position of the turtle as well as drawings of other
+        turtles are not affected.
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.clear()
+        """
+        self._clear()
+        self._update()
+
+    def _update_data(self):
+        self.screen._incrementudc()
+        if self.screen._updatecounter != 0:
+            return
+        if len(self.currentLine)>1:
+            self.screen._drawline(self.currentLineItem, self.currentLine,
+                                  self._pencolor, self._pensize)
+
+    def _update(self):
+        """Perform a Turtle-data update.
+        """
+        screen = self.screen
+        if screen._tracing == 0:
+            return
+        elif screen._tracing == 1:
+            self._update_data()
+            self._drawturtle()
+            screen._update()                  # TurtleScreenBase
+            screen._delay(screen._delayvalue) # TurtleScreenBase
+        else:
+            self._update_data()
+            if screen._updatecounter == 0:
+                for t in screen.turtles():
+                    t._drawturtle()
+                screen._update()
+
+    def _tracer(self, flag=None, delay=None):
+        """Turns turtle animation on/off and set delay for update drawings.
+
+        Optional arguments:
+        n -- nonnegative  integer
+        delay -- nonnegative  integer
+
+        If n is given, only each n-th regular screen update is really performed.
+        (Can be used to accelerate the drawing of complex graphics.)
+        Second arguments sets delay value (see RawTurtle.delay())
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.tracer(8, 25)
+        >>> dist = 2
+        >>> for i in range(200):
+                turtle.fd(dist)
+                turtle.rt(90)
+                dist += 2
+        """
+        return self.screen.tracer(flag, delay)
+
+    def _color(self, args):
+        return self.screen._color(args)
+
+    def _colorstr(self, args):
+        return self.screen._colorstr(args)
+
+    def _cc(self, args):
+        """Convert colortriples to hexstrings.
+        """
+        if isinstance(args, str):
+            return args
+        try:
+            r, g, b = args
+        except:
+            raise TurtleGraphicsError("bad color arguments: %s" % str(args))
+        if self.screen._colormode == 1.0:
+            r, g, b = [round(255.0*x) for x in (r, g, b)]
+        if not ((0 <= r <= 255) and (0 <= g <= 255) and (0 <= b <= 255)):
+            raise TurtleGraphicsError("bad color sequence: %s" % str(args))
+        return "#%02x%02x%02x" % (r, g, b)
+
+    def clone(self):
+        """Create and return a clone of the turtle.
+
+        No argument.
+
+        Create and return a clone of the turtle with same position, heading
+        and turtle properties.
+
+        Example (for a Turtle instance named mick):
+        mick = Turtle()
+        joe = mick.clone()
+        """
+        screen = self.screen
+        self._newLine(self._drawing)
+
+        turtle = self.turtle
+        self.screen = None
+        self.turtle = None  # too make self deepcopy-able
+
+        q = deepcopy(self)
+
+        self.screen = screen
+        self.turtle = turtle
+
+        q.screen = screen
+        q.turtle = _TurtleImage(screen, self.turtle.shapeIndex)
+
+        screen._turtles.append(q)
+        ttype = screen._shapes[self.turtle.shapeIndex]._type
+        if ttype == "polygon":
+            q.turtle._item = screen._createpoly()
+        elif ttype == "image":
+            q.turtle._item = screen._createimage(screen._shapes["blank"]._data)
+        elif ttype == "compound":
+            q.turtle._item = [screen._createpoly() for item in
+                              screen._shapes[self.turtle.shapeIndex]._data]
+        q.currentLineItem = screen._createline()
+        q._update()
+        return q
+
+    def shape(self, name=None):
+        """Set turtle shape to shape with given name / return current shapename.
+
+        Optional argument:
+        name -- a string, which is a valid shapename
+
+        Set turtle shape to shape with given name or, if name is not given,
+        return name of current shape.
+        Shape with name must exist in the TurtleScreen's shape dictionary.
+        Initially there are the following polygon shapes:
+        'arrow', 'turtle', 'circle', 'square', 'triangle', 'classic'.
+        To learn about how to deal with shapes see Screen-method register_shape.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.shape()
+        'arrow'
+        >>> turtle.shape("turtle")
+        >>> turtle.shape()
+        'turtle'
+        """
+        if name is None:
+            return self.turtle.shapeIndex
+        if not name in self.screen.getshapes():
+            raise TurtleGraphicsError("There is no shape named %s" % name)
+        self.turtle._setshape(name)
+        self._update()
+
+    def shapesize(self, stretch_wid=None, stretch_len=None, outline=None):
+        """Set/return turtle's stretchfactors/outline. Set resizemode to "user".
+
+        Optinonal arguments:
+           stretch_wid : positive number
+           stretch_len : positive number
+           outline  : positive number
+
+        Return or set the pen's attributes x/y-stretchfactors and/or outline.
+        Set resizemode to "user".
+        If and only if resizemode is set to "user", the turtle will be displayed
+        stretched according to its stretchfactors:
+        stretch_wid is stretchfactor perpendicular to orientation
+        stretch_len is stretchfactor in direction of turtles orientation.
+        outline determines the width of the shapes's outline.
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.resizemode("user")
+        >>> turtle.shapesize(5, 5, 12)
+        >>> turtle.shapesize(outline=8)
+        """
+        if stretch_wid is None and stretch_len is None and outline == None:
+            stretch_wid, stretch_len = self._stretchfactor
+            return stretch_wid, stretch_len, self._outlinewidth
+        if stretch_wid is not None:
+            if stretch_len is None:
+                stretchfactor = stretch_wid, stretch_wid
+            else:
+                stretchfactor = stretch_wid, stretch_len
+        elif stretch_len is not None:
+            stretchfactor = self._stretchfactor[0], stretch_len
+        else:
+            stretchfactor = self._stretchfactor
+        if outline is None:
+            outline = self._outlinewidth
+        self.pen(resizemode="user",
+                 stretchfactor=stretchfactor, outline=outline)
+
+    def settiltangle(self, angle):
+        """Rotate the turtleshape to point in the specified direction
+
+        Optional argument:
+        angle -- number
+
+        Rotate the turtleshape to point in the direction specified by angle,
+        regardless of its current tilt-angle. DO NOT change the turtle's
+        heading (direction of movement).
+
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.settiltangle(45)
+        >>> stamp()
+        >>> turtle.fd(50)
+        >>> turtle.settiltangle(-45)
+        >>> stamp()
+        >>> turtle.fd(50)
+        """
+        tilt = -angle * self._degreesPerAU * self._angleOrient
+        tilt = (tilt * math.pi / 180.0) % (2*math.pi)
+        self.pen(resizemode="user", tilt=tilt)
+
+    def tiltangle(self):
+        """Return the current tilt-angle.
+
+        No argument.
+
+        Return the current tilt-angle, i. e. the angle between the
+        orientation of the turtleshape and the heading of the turtle
+        (it's direction of movement).
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.tilt(45)
+        >>> turtle.tiltangle()
+        >>>
+        """
+        tilt = -self._tilt * (180.0/math.pi) * self._angleOrient
+        return (tilt / self._degreesPerAU) % self._fullcircle
+
+    def tilt(self, angle):
+        """Rotate the turtleshape by angle.
+
+        Argument:
+        angle - a number
+
+        Rotate the turtleshape by angle from its current tilt-angle,
+        but do NOT change the turtle's heading (direction of movement).
+
+        Examples (for a Turtle instance named turtle):
+        >>> turtle.shape("circle")
+        >>> turtle.shapesize(5,2)
+        >>> turtle.tilt(30)
+        >>> turtle.fd(50)
+        >>> turtle.tilt(30)
+        >>> turtle.fd(50)
+        """
+        self.settiltangle(angle + self.tiltangle())
+
+    def _polytrafo(self, poly):
+        """Computes transformed polygon shapes from a shape
+        according to current position and heading.
+        """
+        screen = self.screen
+        p0, p1 = self._position
+        e0, e1 = self._orient
+        e = Vec2D(e0, e1 * screen.yscale / screen.xscale)
+        e0, e1 = (1.0 / abs(e)) * e
+        return [(p0+(e1*x+e0*y)/screen.xscale, p1+(-e0*x+e1*y)/screen.yscale)
+                                                           for (x, y) in poly]
+
+    def _drawturtle(self):
+        """Manages the correct rendering of the turtle with respect to
+        it's shape, resizemode, strech and tilt etc."""
+        screen = self.screen
+        shape = screen._shapes[self.turtle.shapeIndex]
+        ttype = shape._type
+        titem = self.turtle._item
+        if self._shown and screen._updatecounter == 0 and screen._tracing > 0:
+            self._hidden_from_screen = False
+            tshape = shape._data
+            if ttype == "polygon":
+                if self._resizemode == "noresize":
+                    w = 1
+                    shape = tshape
+                else:
+                    if self._resizemode == "auto":
+                        lx = ly = max(1, self._pensize/5.0)
+                        w = self._pensize
+                        tiltangle = 0
+                    elif self._resizemode == "user":
+                        lx, ly = self._stretchfactor
+                        w = self._outlinewidth
+                        tiltangle = self._tilt
+                    shape = [(lx*x, ly*y) for (x, y) in tshape]
+                    t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+                    shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+                shape = self._polytrafo(shape)
+                fc, oc = self._fillcolor, self._pencolor
+                screen._drawpoly(titem, shape, fill=fc, outline=oc,
+                                                      width=w, top=True)
+            elif ttype == "image":
+                screen._drawimage(titem, self._position, tshape)
+            elif ttype == "compound":
+                lx, ly = self._stretchfactor
+                w = self._outlinewidth
+                for item, (poly, fc, oc) in zip(titem, tshape):
+                    poly = [(lx*x, ly*y) for (x, y) in poly]
+                    poly = self._polytrafo(poly)
+                    screen._drawpoly(item, poly, fill=self._cc(fc),
+                                     outline=self._cc(oc), width=w, top=True)
+        else:
+            if self._hidden_from_screen:
+                return
+            if ttype == "polygon":
+                screen._drawpoly(titem, ((0, 0), (0, 0), (0, 0)), "", "")
+            elif ttype == "image":
+                screen._drawimage(titem, self._position,
+                                          screen._shapes["blank"]._data)
+            elif ttype == "compound":
+                for item in titem:
+                    screen._drawpoly(item, ((0, 0), (0, 0), (0, 0)), "", "")
+            self._hidden_from_screen = True
+
+##############################  stamp stuff  ###############################
+
+    def stamp(self):
+        """Stamp a copy of the turtleshape onto the canvas and return it's id.
+
+        No argument.
+
+        Stamp a copy of the turtle shape onto the canvas at the current
+        turtle position. Return a stamp_id for that stamp, which can be
+        used to delete it by calling clearstamp(stamp_id).
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("blue")
+        >>> turtle.stamp()
+        13
+        >>> turtle.fd(50)
+        """
+        screen = self.screen
+        shape = screen._shapes[self.turtle.shapeIndex]
+        ttype = shape._type
+        tshape = shape._data
+        if ttype == "polygon":
+            stitem = screen._createpoly()
+            if self._resizemode == "noresize":
+                w = 1
+                shape = tshape
+            else:
+                if self._resizemode == "auto":
+                    lx = ly = max(1, self._pensize/5.0)
+                    w = self._pensize
+                    tiltangle = 0
+                elif self._resizemode == "user":
+                    lx, ly = self._stretchfactor
+                    w = self._outlinewidth
+                    tiltangle = self._tilt
+                shape = [(lx*x, ly*y) for (x, y) in tshape]
+                t0, t1 = math.sin(tiltangle), math.cos(tiltangle)
+                shape = [(t1*x+t0*y, -t0*x+t1*y) for (x, y) in shape]
+            shape = self._polytrafo(shape)
+            fc, oc = self._fillcolor, self._pencolor
+            screen._drawpoly(stitem, shape, fill=fc, outline=oc,
+                                                  width=w, top=True)
+        elif ttype == "image":
+            stitem = screen._createimage("")
+            screen._drawimage(stitem, self._position, tshape)
+        elif ttype == "compound":
+            stitem = []
+            for element in tshape:
+                item = screen._createpoly()
+                stitem.append(item)
+            stitem = tuple(stitem)
+            lx, ly = self._stretchfactor
+            w = self._outlinewidth
+            for item, (poly, fc, oc) in zip(stitem, tshape):
+                poly = [(lx*x, ly*y) for (x, y) in poly]
+                poly = self._polytrafo(poly)
+                screen._drawpoly(item, poly, fill=self._cc(fc),
+                                 outline=self._cc(oc), width=w, top=True)
+        self.stampItems.append(stitem)
+        self.undobuffer.push(("stamp", stitem))
+        return stitem
+
+    def _clearstamp(self, stampid):
+        """does the work for clearstamp() and clearstamps()
+        """
+        if stampid in self.stampItems:
+            if isinstance(stampid, tuple):
+                for subitem in stampid:
+                    self.screen._delete(subitem)
+            else:
+                self.screen._delete(stampid)
+            self.stampItems.remove(stampid)
+        # Delete stampitem from undobuffer if necessary
+        # if clearstamp is called directly.
+        item = ("stamp", stampid)
+        buf = self.undobuffer
+        if item not in buf.buffer:
+            return
+        index = buf.buffer.index(item)
+        buf.buffer.remove(item)
+        if index <= buf.ptr:
+            buf.ptr = (buf.ptr - 1) % buf.bufsize
+        buf.buffer.insert((buf.ptr+1)%buf.bufsize, [None])
+
+    def clearstamp(self, stampid):
+        """Delete stamp with given stampid
+
+        Argument:
+        stampid - an integer, must be return value of previous stamp() call.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("blue")
+        >>> astamp = turtle.stamp()
+        >>> turtle.fd(50)
+        >>> turtle.clearstamp(astamp)
+        """
+        self._clearstamp(stampid)
+        self._update()
+
+    def clearstamps(self, n=None):
+        """Delete all or first/last n of turtle's stamps.
+
+        Optional argument:
+        n -- an integer
+
+        If n is None, delete all of pen's stamps,
+        else if n > 0 delete first n stamps
+        else if n < 0 delete last n stamps.
+
+        Example (for a Turtle instance named turtle):
+        >>> for i in range(8):
+                turtle.stamp(); turtle.fd(30)
+        ...
+        >>> turtle.clearstamps(2)
+        >>> turtle.clearstamps(-2)
+        >>> turtle.clearstamps()
+        """
+        if n is None:
+            toDelete = self.stampItems[:]
+        elif n >= 0:
+            toDelete = self.stampItems[:n]
+        else:
+            toDelete = self.stampItems[n:]
+        for item in toDelete:
+            self._clearstamp(item)
+        self._update()
+
+    def _goto(self, end):
+        """Move the pen to the point end, thereby drawing a line
+        if pen is down. All other methodes for turtle movement depend
+        on this one.
+        """
+        ## Version mit undo-stuff
+        go_modes = ( self._drawing,
+                     self._pencolor,
+                     self._pensize,
+                     isinstance(self._fillpath, list))
+        screen = self.screen
+        undo_entry = ("go", self._position, end, go_modes,
+                      (self.currentLineItem,
+                      self.currentLine[:],
+                      screen._pointlist(self.currentLineItem),
+                      self.items[:])
+                      )
+        if self.undobuffer:
+            self.undobuffer.push(undo_entry)
+        start = self._position
+        if self._speed and screen._tracing == 1:
+            diff = (end-start)
+            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+            delta = diff * (1.0/nhops)
+            for n in range(1, nhops):
+                if n == 1:
+                    top = True
+                else:
+                    top = False
+                self._position = start + delta * n
+                if self._drawing:
+                    screen._drawline(self.drawingLineItem,
+                                     (start, self._position),
+                                     self._pencolor, self._pensize, top)
+                self._update()
+            if self._drawing:
+                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+                                               fill="", width=self._pensize)
+        # Turtle now at end,
+        if self._drawing: # now update currentLine
+            self.currentLine.append(end)
+        if isinstance(self._fillpath, list):
+            self._fillpath.append(end)
+        ######    vererbung!!!!!!!!!!!!!!!!!!!!!!
+        self._position = end
+        if self._creatingPoly:
+            self._poly.append(end)
+        if len(self.currentLine) > 42: # 42! answer to the ultimate question
+                                       # of life, the universe and everything
+            self._newLine()
+        self._update() #count=True)
+
+    def _undogoto(self, entry):
+        """Reverse a _goto. Used for undo()
+        """
+        old, new, go_modes, coodata = entry
+        drawing, pc, ps, filling = go_modes
+        cLI, cL, pl, items = coodata
+        screen = self.screen
+        if abs(self._position - new) > 0.5:
+            print ("undogoto: HALLO-DA-STIMMT-WAS-NICHT!")
+        # restore former situation
+        self.currentLineItem = cLI
+        self.currentLine = cL
+
+        if pl == [(0, 0), (0, 0)]:
+            usepc = ""
+        else:
+            usepc = pc
+        screen._drawline(cLI, pl, fill=usepc, width=ps)
+
+        todelete = [i for i in self.items if (i not in items) and
+                                       (screen._type(i) == "line")]
+        for i in todelete:
+            screen._delete(i)
+            self.items.remove(i)
+
+        start = old
+        if self._speed and screen._tracing == 1:
+            diff = old - new
+            diffsq = (diff[0]*screen.xscale)**2 + (diff[1]*screen.yscale)**2
+            nhops = 1+int((diffsq**0.5)/(3*(1.1**self._speed)*self._speed))
+            delta = diff * (1.0/nhops)
+            for n in range(1, nhops):
+                if n == 1:
+                    top = True
+                else:
+                    top = False
+                self._position = new + delta * n
+                if drawing:
+                    screen._drawline(self.drawingLineItem,
+                                     (start, self._position),
+                                     pc, ps, top)
+                self._update()
+            if drawing:
+                screen._drawline(self.drawingLineItem, ((0, 0), (0, 0)),
+                                               fill="", width=ps)
+        # Turtle now at position old,
+        self._position = old
+        ##  if undo is done during crating a polygon, the last vertex
+        ##  will be deleted. if the polygon is entirel deleted,
+        ##  creatigPoly will be set to False.
+        ##  Polygons created before the last one will not be affected by undo()
+        if self._creatingPoly:
+            if len(self._poly) > 0:
+                self._poly.pop()
+            if self._poly == []:
+                self._creatingPoly = False
+                self._poly = None
+        if filling:
+            if self._fillpath == []:
+                self._fillpath = None
+                print("Unwahrscheinlich in _undogoto!")
+            elif self._fillpath is not None:
+                self._fillpath.pop()
+        self._update() #count=True)
+
+    def _rotate(self, angle):
+        """Turns pen clockwise by angle.
+        """
+        if self.undobuffer:
+            self.undobuffer.push(("rot", angle, self._degreesPerAU))
+        angle *= self._degreesPerAU
+        neworient = self._orient.rotate(angle)
+        tracing = self.screen._tracing
+        if tracing == 1 and self._speed > 0:
+            anglevel = 3.0 * self._speed
+            steps = 1 + int(abs(angle)/anglevel)
+            delta = 1.0*angle/steps
+            for _ in range(steps):
+                self._orient = self._orient.rotate(delta)
+                self._update()
+        self._orient = neworient
+        self._update()
+
+    def _newLine(self, usePos=True):
+        """Closes current line item and starts a new one.
+           Remark: if current line became too long, animation
+           performance (via _drawline) slowed down considerably.
+        """
+        if len(self.currentLine) > 1:
+            self.screen._drawline(self.currentLineItem, self.currentLine,
+                                      self._pencolor, self._pensize)
+            self.currentLineItem = self.screen._createline()
+            self.items.append(self.currentLineItem)
+        else:
+            self.screen._drawline(self.currentLineItem, top=True)
+        self.currentLine = []
+        if usePos:
+            self.currentLine = [self._position]
+
+    def filling(self):
+        """Return fillstate (True if filling, False else).
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.begin_fill()
+        >>> if turtle.filling():
+                turtle.pensize(5)
+        else:
+                turtle.pensize(3)
+        """
+        return isinstance(self._fillpath, list)
+
+##    def fill(self, flag=None):
+##        """Call fill(True) before drawing a shape to fill, fill(False) when done.
+##
+##        Optional argument:
+##        flag -- True/False (or 1/0 respectively)
+##
+##        Call fill(True) before drawing the shape you want to fill,
+##        and  fill(False) when done.
+##        When used without argument: return fillstate (True if filling,
+##        False else)
+##
+##        Example (for a Turtle instance named turtle):
+##        >>> turtle.fill(True)
+##        >>> turtle.forward(100)
+##        >>> turtle.left(90)
+##        >>> turtle.forward(100)
+##        >>> turtle.left(90)
+##        >>> turtle.forward(100)
+##        >>> turtle.left(90)
+##        >>> turtle.forward(100)
+##        >>> turtle.fill(False)
+##        """
+##        filling = isinstance(self._fillpath, list)
+##        if flag is None:
+##            return filling
+##        screen = self.screen
+##        entry1 = entry2 = ()
+##        if filling:
+##            if len(self._fillpath) > 2:
+##                self.screen._drawpoly(self._fillitem, self._fillpath,
+##                                      fill=self._fillcolor)
+##                entry1 = ("dofill", self._fillitem)
+##        if flag:
+##            self._fillitem = self.screen._createpoly()
+##            self.items.append(self._fillitem)
+##            self._fillpath = [self._position]
+##            entry2 = ("beginfill", self._fillitem) # , self._fillpath)
+##            self._newLine()
+##        else:
+##            self._fillitem = self._fillpath = None
+##        if self.undobuffer:
+##            if entry1 == ():
+##                if entry2 != ():
+##                    self.undobuffer.push(entry2)
+##            else:
+##                if entry2 == ():
+##                    self.undobuffer.push(entry1)
+##                else:
+##                    self.undobuffer.push(["seq", entry1, entry2])
+##        self._update()
+
+    def begin_fill(self):
+        """Called just before drawing a shape to be filled.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("black", "red")
+        >>> turtle.begin_fill()
+        >>> turtle.circle(60)
+        >>> turtle.end_fill()
+        """
+        if not self.filling():
+            self._fillitem = self.screen._createpoly()
+            self.items.append(self._fillitem)
+        self._fillpath = [self._position]
+        self._newLine()
+        if self.undobuffer:
+            self.undobuffer.push(("beginfill", self._fillitem))
+        self._update()
+
+
+    def end_fill(self):
+        """Fill the shape drawn after the call begin_fill().
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.color("black", "red")
+        >>> turtle.begin_fill()
+        >>> turtle.circle(60)
+        >>> turtle.end_fill()
+        """
+        if self.filling():
+            if len(self._fillpath) > 2:
+                self.screen._drawpoly(self._fillitem, self._fillpath,
+                                      fill=self._fillcolor)
+                if self.undobuffer:
+                    self.undobuffer.push(("dofill", self._fillitem))
+            self._fillitem = self._fillpath = None
+            self._update()
+
+    def dot(self, size=None, *color):
+        """Draw a dot with diameter size, using color.
+
+        Optional argumentS:
+        size -- an integer >= 1 (if given)
+        color -- a colorstring or a numeric color tuple
+
+        Draw a circular dot with diameter size, using color.
+        If size is not given, the maximum of pensize+4 and 2*pensize is used.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.dot()
+        >>> turtle.fd(50); turtle.dot(20, "blue"); turtle.fd(50)
+        """
+        #print "dot-1:", size, color
+        if not color:
+            if isinstance(size, (str, tuple)):
+                color = self._colorstr(size)
+                size = self._pensize + max(self._pensize, 4)
+            else:
+                color = self._pencolor
+                if not size:
+                    size = self._pensize + max(self._pensize, 4)
+        else:
+            if size is None:
+                size = self._pensize + max(self._pensize, 4)
+            color = self._colorstr(color)
+        #print "dot-2:", size, color
+        if hasattr(self.screen, "_dot"):
+            item = self.screen._dot(self._position, size, color)
+            #print "dot:", size, color, "item:", item
+            self.items.append(item)
+            if self.undobuffer:
+                self.undobuffer.push(("dot", item))
+        else:
+            pen = self.pen()
+            if self.undobuffer:
+                self.undobuffer.push(["seq"])
+                self.undobuffer.cumulate = True
+            try:
+                if self.resizemode() == 'auto':
+                    self.ht()
+                self.pendown()
+                self.pensize(size)
+                self.pencolor(color)
+                self.forward(0)
+            finally:
+                self.pen(pen)
+            if self.undobuffer:
+                self.undobuffer.cumulate = False
+
+    def _write(self, txt, align, font):
+        """Performs the writing for write()
+        """
+        item, end = self.screen._write(self._position, txt, align, font,
+                                                          self._pencolor)
+        self.items.append(item)
+        if self.undobuffer:
+            self.undobuffer.push(("wri", item))
+        return end
+
+    def write(self, arg, move=False, align="left", font=("Arial", 8, "normal")):
+        """Write text at the current turtle position.
+
+        Arguments:
+        arg -- info, which is to be written to the TurtleScreen
+        move (optional) -- True/False
+        align (optional) -- one of the strings "left", "center" or right"
+        font (optional) -- a triple (fontname, fontsize, fonttype)
+
+        Write text - the string representation of arg - at the current
+        turtle position according to align ("left", "center" or right")
+        and with the given font.
+        If move is True, the pen is moved to the bottom-right corner
+        of the text. By default, move is False.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.write('Home = ', True, align="center")
+        >>> turtle.write((0,0), True)
+        """
+        if self.undobuffer:
+            self.undobuffer.push(["seq"])
+            self.undobuffer.cumulate = True
+        end = self._write(str(arg), align.lower(), font)
+        if move:
+            x, y = self.pos()
+            self.setpos(end, y)
+        if self.undobuffer:
+            self.undobuffer.cumulate = False
+
+    def begin_poly(self):
+        """Start recording the vertices of a polygon.
+
+        No argument.
+
+        Start recording the vertices of a polygon. Current turtle position
+        is first point of polygon.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.begin_poly()
+        """
+        self._poly = [self._position]
+        self._creatingPoly = True
+
+    def end_poly(self):
+        """Stop recording the vertices of a polygon.
+
+        No argument.
+
+        Stop recording the vertices of a polygon. Current turtle position is
+        last point of polygon. This will be connected with the first point.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.end_poly()
+        """
+        self._creatingPoly = False
+
+    def get_poly(self):
+        """Return the lastly recorded polygon.
+
+        No argument.
+
+        Example (for a Turtle instance named turtle):
+        >>> p = turtle.get_poly()
+        >>> turtle.register_shape("myFavouriteShape", p)
+        """
+        ## check if there is any poly?  -- 1st solution:
+        if self._poly is not None:
+            return tuple(self._poly)
+
+    def getscreen(self):
+        """Return the TurtleScreen object, the turtle is drawing  on.
+
+        No argument.
+
+        Return the TurtleScreen object, the turtle is drawing  on.
+        So TurtleScreen-methods can be called for that object.
+
+        Example (for a Turtle instance named turtle):
+        >>> ts = turtle.getscreen()
+        >>> ts
+        <turtle.TurtleScreen object at 0x0106B770>
+        >>> ts.bgcolor("pink")
+        """
+        return self.screen
+
+    def getturtle(self):
+        """Return the Turtleobject itself.
+
+        No argument.
+
+        Only reasonable use: as a function to return the 'anonymous turtle':
+
+        Example:
+        >>> pet = getturtle()
+        >>> pet.fd(50)
+        >>> pet
+        <turtle.Turtle object at 0x0187D810>
+        >>> turtles()
+        [<turtle.Turtle object at 0x0187D810>]
+        """
+        return self
+
+    getpen = getturtle
+
+
+    ################################################################
+    ### screen oriented methods recurring to methods of TurtleScreen
+    ################################################################
+
+##    def window_width(self):
+##        """ Returns the width of the turtle window.
+##
+##        No argument.
+##
+##        Example (for a TurtleScreen instance named screen):
+##        >>> screen.window_width()
+##        640
+##        """
+##        return self.screen._window_size()[0]
+##
+##    def window_height(self):
+##        """ Return the height of the turtle window.
+##
+##        No argument.
+##
+##        Example (for a TurtleScreen instance named screen):
+##        >>> screen.window_height()
+##        480
+##        """
+##        return self.screen._window_size()[1]
+
+    def _delay(self, delay=None):
+        """Set delay value which determines speed of turtle animation.
+        """
+        return self.screen.delay(delay)
+
+    #####   event binding methods   #####
+
+    def onclick(self, fun, btn=1, add=None):
+        """Bind fun to mouse-click event on this turtle on canvas.
+
+        Arguments:
+        fun --  a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+        add --  True or False. If True, new binding will be added, otherwise
+                it will replace a former binding.
+
+        Example for the anonymous turtle, i. e. the procedural way:
+
+        >>> def turn(x, y):
+                left(360)
+
+        >>> onclick(turn) # Now clicking into the turtle will turn it.
+        >>> onclick(None)  # event-binding will be removed
+        """
+        self.screen._onclick(self.turtle._item, fun, btn, add)
+        self._update()
+
+    def onrelease(self, fun, btn=1, add=None):
+        """Bind fun to mouse-button-release event on this turtle on canvas.
+
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+                the coordinates of the clicked point on the canvas.
+        num --  number of the mouse-button defaults to 1 (left mouse button).
+
+        Example (for a MyTurtle instance named joe):
+        >>> class MyTurtle(Turtle):
+                def glow(self,x,y):
+                        self.fillcolor("red")
+                def unglow(self,x,y):
+                        self.fillcolor("")
+
+        >>> joe = MyTurtle()
+        >>> joe.onclick(joe.glow)
+        >>> joe.onrelease(joe.unglow)
+        ### clicking on joe turns fillcolor red,
+        ### unclicking turns it to transparent.
+        """
+        self.screen._onrelease(self.turtle._item, fun, btn, add)
+        self._update()
+
+    def ondrag(self, fun, btn=1, add=None):
+        """Bind fun to mouse-move event on this turtle on canvas.
+
+        Arguments:
+        fun -- a function with two arguments, to which will be assigned
+               the coordinates of the clicked point on the canvas.
+        num -- number of the mouse-button defaults to 1 (left mouse button).
+
+        Every sequence of mouse-move-events on a turtle is preceded by a
+        mouse-click event on that turtle.
+
+        Example (for a Turtle instance named turtle):
+        >>> turtle.ondrag(turtle.goto)
+
+        ### Subsequently clicking and dragging a Turtle will
+        ### move it across the screen thereby producing handdrawings
+        ### (if pen is down).
+        """
+        self.screen._ondrag(self.turtle._item, fun, btn, add)
+
+
+    def _undo(self, action, data):
+        """Does the main part of the work for undo()
+        """
+        if self.undobuffer is None:
+            return
+        if action == "rot":
+            angle, degPAU = data
+            self._rotate(-angle*degPAU/self._degreesPerAU)
+            dummy = self.undobuffer.pop()
+        elif action == "stamp":
+            stitem = data[0]
+            self.clearstamp(stitem)
+        elif action == "go":
+            self._undogoto(data)
+        elif action in ["wri", "dot"]:
+            item = data[0]
+            self.screen._delete(item)
+            self.items.remove(item)
+        elif action == "dofill":
+            item = data[0]
+            self.screen._drawpoly(item, ((0, 0),(0, 0),(0, 0)),
+                                  fill="", outline="")
+        elif action == "beginfill":
+            item = data[0]
+            self._fillitem = self._fillpath = None
+            if item in self.items:
+                self.screen._delete(item)
+                self.items.remove(item)
+        elif action == "pen":
+            TPen.pen(self, data[0])
+            self.undobuffer.pop()
+
+    def undo(self):
+        """undo (repeatedly) the last turtle action.
+
+        No argument.
+
+        undo (repeatedly) the last turtle action.
+        Number of available undo actions is determined by the size of
+        the undobuffer.
+
+        Example (for a Turtle instance named turtle):
+        >>> for i in range(4):
+                turtle.fd(50); turtle.lt(80)
+
+        >>> for i in range(8):
+                turtle.undo()
+        """
+        if self.undobuffer is None:
+            return
+        item = self.undobuffer.pop()
+        action = item[0]
+        data = item[1:]
+        if action == "seq":
+            while data:
+                item = data.pop()
+                self._undo(item[0], item[1:])
+        else:
+            self._undo(action, data)
+
+    turtlesize = shapesize
+
+RawPen = RawTurtle
+
+###  Screen - Klasse  ########################
+
+class Screen(TurtleScreen):
+
+    _root = None
+    _canvas = None
+    _title = _CFG["title"]
+
+    # Borg-Idiom
+
+    _shared_state = {}
+
+    def __new__(cls, *args, **kwargs):
+        obj = object.__new__(cls, *args, **kwargs)
+        obj.__dict__ = cls._shared_state
+        return obj
 
     def __init__(self):
-        global _root, _canvas
-        if _root is None:
-            _root = tkinter.Tk()
-            _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
-            _root.title(_title)
+        if Screen._root is None:
+            Screen._root = self._root = _Root()
+            self._root.title(Screen._title)
+            self._root.ondestroy(self._destroy)
+        if Screen._canvas is None:
+            width = _CFG["width"]
+            height = _CFG["height"]
+            canvwidth = _CFG["canvwidth"]
+            canvheight = _CFG["canvheight"]
+            leftright = _CFG["leftright"]
+            topbottom = _CFG["topbottom"]
+            self._root.setupcanvas(width, height, canvwidth, canvheight)
+            Screen._canvas = self._root._getcanvas()
+            self.setup(width, height, leftright, topbottom)
+            TurtleScreen.__init__(self, Screen._canvas)
+        Turtle._screen = self
 
-        if _canvas is None:
-            # XXX Should have scroll bars
-            _canvas = tkinter.Canvas(_root, background="white")
-            _canvas.pack(expand=1, fill="both")
+    def setup(self, width=_CFG["width"], height=_CFG["height"],
+              startx=_CFG["leftright"], starty=_CFG["topbottom"]):
+        """ Set the size and position of the main window.
 
-            setup(width=_width, height= _height, startx=_startx, starty=_starty)
+        Arguments:
+        width: as integer a size in pixels, as float a fraction of the screen.
+          Default is 50% of screen.
+        height: as integer the height in pixels, as float a fraction of the
+          screen. Default is 75% of screen.
+        startx: if positive, starting position in pixels from the left
+          edge of the screen, if negative from the right edge
+          Default, startx=None is to center window horizontally.
+        starty: if positive, starting position in pixels from the top
+          edge of the screen, if negative from the bottom edge
+          Default, starty=None is to center window vertically.
 
-        RawPen.__init__(self, _canvas)
+        Examples (for a Screen instance named screen):
+        >>> screen.setup (width=200, height=200, startx=0, starty=0)
+
+        sets window to 200x200 pixels, in upper left of screen
+
+        >>> screen.setup(width=.75, height=0.5, startx=None, starty=None)
+
+        sets window to 75% of screen by 50% of screen and centers
+        """
+        if not hasattr(self._root, "set_geometry"):
+            return
+        sw = self._root.win_width()
+        sh = self._root.win_height()
+        if isinstance(width, float) and 0 <= width <= 1:
+            width = sw*width
+        if startx is None:
+            startx = (sw - width) / 2
+        if isinstance(height, float) and 0 <= height <= 1:
+            height = sh*height
+        if starty is None:
+            starty = (sh - height) / 2
+        self._root.set_geometry(width, height, startx, starty)
+
+    def title(self, titlestring):
+        """Set title of turtle-window
+
+        Argument:
+        titlestring -- a string, to appear in the titlebar of the
+                       turtle graphics window.
+
+        This is a method of Screen-class. Not available for TurtleScreen-
+        objects.
+
+        Example (for a Screen instance named screen):
+        >>> screen.title("Welcome to the turtle-zoo!")
+        """
+        if Screen._root is not None:
+            Screen._root.title(titlestring)
+        Screen._title = titlestring
 
     def _destroy(self):
-        global _root, _canvas, _pen
-        root = self._canvas._root()
-        if root is _root:
-            _pen = None
-            _root = None
-            _canvas = None
+        root = self._root
+        if root is Screen._root:
+            Turtle._pen = None
+            Turtle._screen = None
+            Screen._root = None
+            Screen._canvas = None
+        TurtleScreen._RUNNING = True
         root.destroy()
 
+    def bye(self):
+        """Shut the turtlegraphics window.
+
+        Example (for a TurtleScreen instance named screen):
+        >>> screen.bye()
+        """
+        self._destroy()
+
+    def exitonclick(self):
+        """Go into mainloop until the mouse is clicked.
+
+        No arguments.
+
+        Bind bye() method to mouseclick on TurtleScreen.
+        If "using_IDLE" - value in configuration dictionary is False
+        (default value), enter mainloop.
+        If IDLE with -n switch (no subprocess) is used, this value should be
+        set to True in turtle.cfg. In this case IDLE's mainloop
+        is active also for the client script.
+
+        This is a method of the Screen-class and not available for
+        TurtleScreen instances.
+
+        Example (for a Screen instance named screen):
+        >>> screen.exitonclick()
+
+        """
+        def exitGracefully(x, y):
+            """Screen.bye() with two dummy-parameters"""
+            self.bye()
+        self.onclick(exitGracefully)
+        if _CFG["using_IDLE"]:
+            return
+        try:
+            mainloop()
+        except AttributeError:
+            exit(0)
+
+
+class Turtle(RawTurtle):
+    """RawTurtle auto-crating (scrolled) canvas.
+
+    When a Turtle object is created or a function derived from some
+    Turtle method is called a TurtleScreen object is automatically created.
+    """
+    _pen = None
+    _screen = None
+
+    def __init__(self,
+                 shape=_CFG["shape"],
+                 undobuffersize=_CFG["undobuffersize"],
+                 visible=_CFG["visible"]):
+        if Turtle._screen is None:
+            Turtle._screen = Screen()
+        RawTurtle.__init__(self, Turtle._screen,
+                           shape=shape,
+                           undobuffersize=undobuffersize,
+                           visible=visible)
+
+Pen = Turtle
+
 def _getpen():
-    global _pen
-    if not _pen:
-        _pen = Pen()
-    return _pen
+    """Create the 'anonymous' turtle if not already present."""
+    if Turtle._pen is None:
+        Turtle._pen = Turtle()
+    return Turtle._pen
 
-class Turtle(Pen):
-    pass
+def _getscreen():
+    """Create a TurtleScreen if not already present."""
+    if Turtle._screen is None:
+        Turtle._screen = Screen()
+    return Turtle._screen
 
-"""For documentation of the following functions see
-   the RawPen methods with the same names
-"""
+def write_docstringdict(filename="turtle_docstringdict"):
+    """Create and write docstring-dictionary to file.
 
-def degrees(): _getpen().degrees()
-def radians(): _getpen().radians()
-def reset(): _getpen().reset()
-def clear(): _getpen().clear()
-def tracer(flag): _getpen().tracer(flag)
-def forward(distance): _getpen().forward(distance)
-def backward(distance): _getpen().backward(distance)
-def left(angle): _getpen().left(angle)
-def right(angle): _getpen().right(angle)
-def up(): _getpen().up()
-def down(): _getpen().down()
-def width(width): _getpen().width(width)
-def color(*args): _getpen().color(*args)
-def write(arg, move=0): _getpen().write(arg, move)
-def fill(flag): _getpen().fill(flag)
-def begin_fill(): _getpen().begin_fill()
-def end_fill(): _getpen().end_fill()
-def circle(radius, extent=None): _getpen().circle(radius, extent)
-def goto(*args): _getpen().goto(*args)
-def heading(): return _getpen().heading()
-def setheading(angle): _getpen().setheading(angle)
-def position(): return _getpen().position()
-def window_width(): return _getpen().window_width()
-def window_height(): return _getpen().window_height()
-def setx(xpos): _getpen().setx(xpos)
-def sety(ypos): _getpen().sety(ypos)
-def towards(*args): return _getpen().towards(*args)
+    Optional argument:
+    filename -- a string, used as filename
+                default value is turtle_docstringdict
 
-def done(): _root.mainloop()
-def delay(delay): return _getpen().delay(delay)
-def speed(speed): return _getpen().speed(speed)
-
-for methodname in dir(RawPen):
-    """ copies RawPen docstrings to module functions of same name """
-    if not methodname.startswith("_"):
-        eval(methodname).__doc__ = RawPen.__dict__[methodname].__doc__
-
-
-def setup(**geometry):
-    """ Sets the size and position of the main window.
-
-    Keywords are width, height, startx and starty:
-
-    width: either a size in pixels or a fraction of the screen.
-      Default is 50% of screen.
-    height: either the height in pixels or a fraction of the screen.
-      Default is 75% of screen.
-
-    Setting either width or height to None before drawing will force
-      use of default geometry as in older versions of turtle.py
-
-    startx: starting position in pixels from the left edge of the screen.
-      Default is to center window. Setting startx to None is the default
-      and centers window horizontally on screen.
-
-    starty: starting position in pixels from the top edge of the screen.
-      Default is to center window. Setting starty to None is the default
-      and centers window vertically on screen.
-
-    Examples:
-    >>> setup (width=200, height=200, startx=0, starty=0)
-
-    sets window to 200x200 pixels, in upper left of screen
-
-    >>> setup(width=.75, height=0.5, startx=None, starty=None)
-
-    sets window to 75% of screen by 50% of screen and centers
-
-    >>> setup(width=None)
-
-    forces use of default geometry as in older versions of turtle.py
+    Has to be called explicitely, (not used by the turtle-graphics classes)
+    The docstring dictionary will be written to the Python script <filname>.py
+    It is intended to serve as a template for translation of the docstrings
+    into different languages.
     """
+    docsdict = {}
 
-    global _width, _height, _startx, _starty
+    for methodname in _tg_screen_functions:
+        key = "Screen."+methodname
+        docsdict[key] = eval(key).__doc__
+    for methodname in _tg_turtle_functions:
+        key = "Turtle."+methodname
+        docsdict[key] = eval(key).__doc__
 
-    width = geometry.get('width',_width)
-    if width >= 0 or width is None:
-        _width = width
-    else:
-        raise ValueError("width can not be less than 0")
+    f = open("%s.py" % filename,"w")
+    keys = sorted([x for x in docsdict.keys()
+                        if x.split('.')[1] not in _alias_list])
+    f.write('docsdict = {\n\n')
+    for key in keys[:-1]:
+        f.write('%s :\n' % repr(key))
+        f.write('        """%s\n""",\n\n' % docsdict[key])
+    key = keys[-1]
+    f.write('%s :\n' % repr(key))
+    f.write('        """%s\n"""\n\n' % docsdict[key])
+    f.write("}\n")
+    f.close()
 
-    height = geometry.get('height',_height)
-    if height >= 0 or height is None:
-        _height = height
-    else:
-        raise ValueError("height can not be less than 0")
+def read_docstrings(lang):
+    """Read in docstrings from lang-specific docstring dictionary.
 
-    startx = geometry.get('startx', _startx)
-    if startx >= 0 or startx is None:
-        _startx = _startx
-    else:
-        raise ValueError("startx can not be less than 0")
-
-    starty = geometry.get('starty', _starty)
-    if starty >= 0 or starty is None:
-        _starty = starty
-    else:
-        raise ValueError("startx can not be less than 0")
-
-
-    if _root and _width and _height:
-        if 0 < _width <= 1:
-            _width = _root.winfo_screenwidth() * +width
-        if 0 < _height <= 1:
-            _height = _root.winfo_screenheight() * _height
-
-        # center window on screen
-        if _startx is None:
-            _startx = (_root.winfo_screenwidth() - _width) / 2
-
-        if _starty is None:
-            _starty = (_root.winfo_screenheight() - _height) / 2
-
-        _root.geometry("%dx%d+%d+%d" % (_width, _height, _startx, _starty))
-
-def title(title):
-    """Set the window title.
-
-    By default this is set to 'Turtle Graphics'
-
-    Example:
-    >>> title("My Window")
+    Transfer docstrings, translated to lang, from a dictionary-file
+    to the methods of classes Screen and Turtle and - in revised form -
+    to the corresponding functions.
     """
+    modname = "turtle_docstringdict_%(language)s" % {'language':lang.lower()}
+    module = __import__(modname)
+    docsdict = module.docsdict
+    for key in docsdict:
+        try:
+#            eval(key).im_func.__doc__ = docsdict[key]
+            eval(key).__doc__ = docsdict[key]
+        except:
+            print("Bad docstring-entry: %s" % key)
 
-    global _title
-    _title = title
+_LANGUAGE = _CFG["language"]
 
-def demo():
-    reset()
-    tracer(1)
-    up()
-    backward(100)
-    down()
-    # draw 3 squares; the last filled
-    width(3)
-    for i in range(3):
-        if i == 2:
-            fill(1)
-        for j in range(4):
+try:
+    if _LANGUAGE != "english":
+        read_docstrings(_LANGUAGE)
+except ImportError:
+    print("Cannot find docsdict for", _LANGUAGE)
+except:
+    print ("Unknown Error when trying to import %s-docstring-dictionary" %
+                                                                  _LANGUAGE)
+
+
+def getmethparlist(ob):
+    "Get strings describing the arguments for the given object"
+    argText1 = argText2 = ""
+    # bit of a hack for methods - turn it into a function
+    # but we drop the "self" param.
+##    if type(ob)==types.MethodType:
+##       fob = ob.im_func
+##        argOffset = 1
+##    else:
+##        fob = ob
+##        argOffset = 0
+    # Try and build one for Python defined functions
+    argOffset = 1
+##    if type(fob) in [types.FunctionType, types.LambdaType]:
+##        try:
+    counter = ob.__code__.co_argcount
+    items2 = list(ob.__code__.co_varnames[argOffset:counter])
+    realArgs = ob.__code__.co_varnames[argOffset:counter]
+    defaults = ob.__defaults__ or []
+    defaults = list(map(lambda name: "=%s" % repr(name), defaults))
+    defaults = [""] * (len(realArgs)-len(defaults)) + defaults
+    items1 = list(map(lambda arg, dflt: arg+dflt, realArgs, defaults))
+    if ob.__code__.co_flags & 0x4:
+        items1.append("*"+ob.__code__.co_varnames[counter])
+        items2.append("*"+ob.__code__.co_varnames[counter])
+        counter += 1
+    if ob.__code__.co_flags & 0x8:
+        items1.append("**"+ob.__code__.co_varnames[counter])
+        items2.append("**"+ob.__code__.co_varnames[counter])
+    argText1 = ", ".join(items1)
+    argText1 = "(%s)" % argText1
+    argText2 = ", ".join(items2)
+    argText2 = "(%s)" % argText2
+##        except:
+##            pass
+    return argText1, argText2
+
+def _turtle_docrevise(docstr):
+    """To reduce docstrings from RawTurtle class for functions
+    """
+    import re
+    if docstr is None:
+        return None
+    turtlename = _CFG["exampleturtle"]
+    newdocstr = docstr.replace("%s." % turtlename,"")
+    parexp = re.compile(r' \(.+ %s\):' % turtlename)
+    newdocstr = parexp.sub(":", newdocstr)
+    return newdocstr
+
+def _screen_docrevise(docstr):
+    """To reduce docstrings from TurtleScreen class for functions
+    """
+    import re
+    if docstr is None:
+        return None
+    screenname = _CFG["examplescreen"]
+    newdocstr = docstr.replace("%s." % screenname,"")
+    parexp = re.compile(r' \(.+ %s\):' % screenname)
+    newdocstr = parexp.sub(":", newdocstr)
+    return newdocstr
+
+## The following mechanism makes all methods of RawTurtle and Turtle available
+## as functions. So we can enhance, change, add, delete methods to these
+## classes and do not need to change anything here.
+
+
+for methodname in _tg_screen_functions:
+    pl1, pl2 = getmethparlist(eval('Screen.' + methodname))
+    if pl1 == "":
+        print(">>>>>>", pl1, pl2)
+        continue
+    defstr = ("def %(key)s%(pl1)s: return _getscreen().%(key)s%(pl2)s" %
+                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
+##    print("Screen:", defstr)
+    exec(defstr)
+    eval(methodname).__doc__ = _screen_docrevise(eval('Screen.'+methodname).__doc__)
+
+for methodname in _tg_turtle_functions:
+    pl1, pl2 = getmethparlist(eval('Turtle.' + methodname))
+    if pl1 == "":
+        print(">>>>>>", pl1, pl2)
+        continue
+    defstr = ("def %(key)s%(pl1)s: return _getpen().%(key)s%(pl2)s" %
+                                   {'key':methodname, 'pl1':pl1, 'pl2':pl2})
+##    print("Turtle:", defstr)
+    exec(defstr)
+    eval(methodname).__doc__ = _turtle_docrevise(eval('Turtle.'+methodname).__doc__)
+
+
+done = mainloop = TK.mainloop
+#del pl1, pl2, defstr
+
+if __name__ == "__main__":
+    def switchpen():
+        if isdown():
+            pu()
+        else:
+            pd()
+
+    def demo1():
+        """Demo of old turtle.py - module"""
+        reset()
+        tracer(True)
+        up()
+        backward(100)
+        down()
+        # draw 3 squares; the last filled
+        width(3)
+        for i in range(3):
+            if i == 2:
+                begin_fill()
+            for _ in range(4):
+                forward(20)
+                left(90)
+            if i == 2:
+                color("maroon")
+                end_fill()
+            up()
+            forward(30)
+            down()
+        width(1)
+        color("black")
+        # move out of the way
+        tracer(False)
+        up()
+        right(90)
+        forward(100)
+        right(90)
+        forward(100)
+        right(180)
+        down()
+        # some text
+        write("startstart", 1)
+        write("start", 1)
+        color("red")
+        # staircase
+        for i in range(5):
             forward(20)
             left(90)
-        if i == 2:
-            color("maroon")
-            fill(0)
-        up()
-        forward(30)
-        down()
-    width(1)
-    color("black")
-    # move out of the way
-    tracer(0)
-    up()
-    right(90)
-    forward(100)
-    right(90)
-    forward(100)
-    right(180)
-    down()
-    # some text
-    write("startstart", 1)
-    write("start", 1)
-    color("red")
-    # staircase
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    # filled staircase
-    fill(1)
-    for i in range(5):
-        forward(20)
-        left(90)
-        forward(20)
-        right(90)
-    fill(0)
-    tracer(1)
-    # more text
-    write("end")
+            forward(20)
+            right(90)
+        # filled staircase
+        tracer(True)
+        begin_fill()
+        for i in range(5):
+            forward(20)
+            left(90)
+            forward(20)
+            right(90)
+        end_fill()
+        # more text
 
-def demo2():
-    # exercises some new and improved features
-    speed('fast')
-    width(3)
+    def demo2():
+        """Demo of some new features."""
+        speed(1)
+        st()
+        pensize(3)
+        setheading(towards(0, 0))
+        radius = distance(0, 0)/2.0
+        rt(90)
+        for _ in range(18):
+            switchpen()
+            circle(radius, 10)
+        write("wait a moment...")
+        while undobufferentries():
+            undo()
+        reset()
+        lt(90)
+        colormode(255)
+        laenge = 10
+        pencolor("green")
+        pensize(3)
+        lt(180)
+        for i in range(-2, 16):
+            if i > 0:
+                begin_fill()
+                fillcolor(255-15*i, 0, 15*i)
+            for _ in range(3):
+                fd(laenge)
+                lt(120)
+            end_fill()
+            laenge += 10
+            lt(15)
+            speed((speed()+1)%12)
+        #end_fill()
 
-    # draw a segmented half-circle
-    setheading(towards(0,0))
-    x,y = position()
-    r = (x**2+y**2)**.5/2.0
-    right(90)
-    pendown = True
-    for i in range(18):
-        if pendown:
-            up()
-            pendown = False
-        else:
-            down()
-            pendown = True
-        circle(r,10)
-    sleep(2)
+        lt(120)
+        pu()
+        fd(70)
+        rt(30)
+        pd()
+        color("red","yellow")
+        speed(0)
+        begin_fill()
+        for _ in range(4):
+            circle(50, 90)
+            rt(90)
+            fd(30)
+            rt(90)
+        end_fill()
+        lt(90)
+        pu()
+        fd(30)
+        pd()
+        shape("turtle")
 
-    reset()
-    left(90)
-
-    # draw a series of triangles
-    l = 10
-    color("green")
-    width(3)
-    left(180)
-    sp = 5
-    for i in range(-2,16):
-        if i > 0:
-            color(1.0-0.05*i,0,0.05*i)
-            fill(1)
-            color("green")
-        for j in range(3):
-            forward(l)
-            left(120)
-        l += 10
-        left(15)
-        if sp > 0:
-            sp = sp-1
-            speed(speeds[sp])
-    color(0.25,0,0.75)
-    fill(0)
-
-    # draw and fill a concave shape
-    left(120)
-    up()
-    forward(70)
-    right(30)
-    down()
-    color("red")
-    speed("fastest")
-    fill(1)
-    for i in range(4):
-        circle(50,90)
-        right(90)
-        forward(30)
-        right(90)
-    color("yellow")
-    fill(0)
-    left(90)
-    up()
-    forward(30)
-    down();
-
-    color("red")
-
-    # create a second turtle and make the original pursue and catch it
-    turtle=Turtle()
-    turtle.reset()
-    turtle.left(90)
-    turtle.speed('normal')
-    turtle.up()
-    turtle.goto(280,40)
-    turtle.left(24)
-    turtle.down()
-    turtle.speed('fast')
-    turtle.color("blue")
-    turtle.width(2)
-    speed('fastest')
-
-    # turn default turtle towards new turtle object
-    setheading(towards(turtle))
-    while ( abs(position()[0]-turtle.position()[0])>4 or
-            abs(position()[1]-turtle.position()[1])>4):
-        turtle.forward(3.5)
-        turtle.left(0.6)
-        # turn default turtle towards new turtle object
+        tri = getturtle()
+        tri.resizemode("auto")
+        turtle = Turtle()
+        turtle.resizemode("auto")
+        turtle.shape("turtle")
+        turtle.reset()
+        turtle.left(90)
+        turtle.speed(0)
+        turtle.up()
+        turtle.goto(280, 40)
+        turtle.lt(30)
+        turtle.down()
+        turtle.speed(6)
+        turtle.color("blue","orange")
+        turtle.pensize(2)
+        tri.speed(6)
         setheading(towards(turtle))
-        forward(4)
-    write("CAUGHT! ", move=True)
+        count = 1
+        while tri.distance(turtle) > 4:
+            turtle.fd(3.5)
+            turtle.lt(0.6)
+            tri.setheading(tri.towards(turtle))
+            tri.fd(4)
+            if count % 20 == 0:
+                turtle.stamp()
+                tri.stamp()
+                switchpen()
+            count += 1
+        tri.write("CAUGHT! ", font=("Arial", 16, "bold"), align="right")
+        tri.pencolor("black")
+        tri.pencolor("red")
 
+        def baba(xdummy, ydummy):
+            clearscreen()
+            bye()
 
+        time.sleep(2)
 
-if __name__ == '__main__':
-    demo()
-    sleep(3)
+        while undobufferentries():
+            tri.undo()
+            turtle.undo()
+        tri.fd(50)
+        tri.write("  Click me!", font = ("Courier", 12, "bold") )
+        tri.onclick(baba, 1)
+
+    demo1()
     demo2()
-    done()
+    exitonclick()
diff --git a/Misc/ACKS b/Misc/ACKS
index eb2a651..7e2c340 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -411,6 +411,7 @@
 Bjorn Lindqvist
 Per Lindqvist
 Eric Lindvall
+Gregor Lingl
 Nick Lockwood
 Stephanie Lockwood
 Anne Lord
