Lufthansa "undef" (ALLP)

1 April 2011

Merkwürdige Abkürzungen ist man gewöhnt wenn man fliegt. Zeit ist hier scheinbar kostbarer als anderswo und ein gewisser eigener Slang grenzt vom gemeinen Volk ab.

In diesem Fall sieht es jedoch anders aus - schon fast schlampig. Offenbar fehlen Übersetzungen, bzw. hinterlegte Texte für den deutschen "Dr." Titel. Offenbar ist man sich auch nicht ganz sicher, wie das Casing denn nun sein soll:

Ich gehe mal davon aus, dass die Flugzeuge besser gewartet und auch getestet werden.

Firefox 4 als Ubuntu Paket installieren

23 March 2011

Firefox 4 ist seit gestern offiziell veröffentlicht worden - auch fuer Linux bzw. Ubuntu. Firefox 4 ist wesentlich schneller als der alte Firefox und verfügt über HTML5 Kompatibilität sowie ein aufgeräumteres Userinterface.

Wer ein Debian basiertes Linux System, wie z.B. Ubuntu, hat, sollte nach Möglichkeit Software über Pakete installieren. Zum Glück gibts es für Ubuntu ein eigenes PPA in dem stabile Versionen von Mozilla nach Veröffentlichung  bereitgestellt werden. Das spart einiges an Arbeit und bietet gegenüber dem Mozilla-Daily PPA den Vorteil, wirklich eine stabile Version zu nutzen.

Wer also unter Ubuntu Firefox 4 schon jetzt nutzen möchte, bevor dieser in den normalen Paketquellen bereitgestellt wird (falls das überhaupt geschieht und nicht erst im nächsten Ubuntu Release), der kann folgendes in eine Kommandozeile eintippen: sudo add-apt-repository ppa:mozillateam/firefox-stable
sudo apt-get update
sudo apt-get upgrade
Viel Spaß mit Firefox 4 unter Ubuntu!

Weitere Neuerungen in Firefox 4:

  • Firefox Sync bietet die Synchronisierung von Bookmarks und Einstellungen über mehrere Rechner
  • Von der neuen - stark beschleunigten - JavaScript Engine profitiert das gesamte Userinterface, nicht nur Webseiten
  • Firefox 4 ist mit vielen Erweiterungen nicht kompatibel (ok, das ist nichts neues nach einem Firefox Update)
  • "do not track" Einstellung für verbesserte Privatssphäre
  • Mein derzeitiger Favorit: App Tabs, mittels Rechtsklick auf ein Tab kann dieser als "permanent" gespeichert werden - praktsch für Twitter, Facebook und co

Wer ein wenig schauen möchte, wo Firefox eingesetzt wird: http://glow.mozilla.org/

Hamcrest, Junit: NoSuchMethodError zur Test Laufzeit

19 March 2011

JUnit 4 bringt die (bessere) Syntax von assertThat über Hamcrest Matcher mit. Und nicht nur die Syntax ist besser, es gibt für viele Testfälle bereits "Matcher", die das Leben erleichtern können.
Genauso kann einem das Leben aber auch erschwert werden: JUnit bringt eben nur ein Subset der Hamcrest Funktionalität mit. Den Rest kann man über die entsprechenden Hamcrest Bibliotheken hinzufügen. Und genau da gilt es nun aufzupassen: JUnit bringt eben bestimmte Versionen der Bilbiotheken mit - und dann kann es zu Konflikten kommen, die sich zur Test-Laufzeit erst zeigen: org.hamcrest.core.AnyOf.anyOf([Lorg/hamcrest/Matcher;)Lorg/hamcrest/core/AnyOf;
java.lang.NoSuchMethodError: org.hamcrest.core.AnyOf.anyOf([Lorg/hamcrest/Matcher;)Lorg/hamcrest/core/AnyOf;
at org.hamcrest.text.IsEmptyString.(IsEmptyString.java:18)
Die Lösung ist dann JUnit ohne eigene Versionen von Hamcrest etc. zu verwenden (die "no-dependencies" Version), und entsprechend die Abhängigkeiten selber aufzulösen.

Mit Maven sieht dann der Einsatz von JUnit, Mockito und Hamcrest z.B. folgendermaßen aus:


<dependency>
  <groupId>junit</groupId>
  <artifactId>junit-dep</artifactId>
  <version>4.8.2</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.mockito</groupId>
  <artifactId>mockito-core</artifactId>
  <version>1.8.5</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-core</artifactId>
  <version>1.2.1</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-library</artifactId>
  <version>1.2.1</version>
  <scope>test</scope>
</dependency>

Pidgin, Ubuntu und Bonjour: Probleme mit ipv6

9 March 2011

Pidgin ist mein bevorzugter IM Client - auch unter Ubuntu Linux. Seit geraumer Zeit jedoch ärgerte mich Pidgin, es gab Probleme mit der Bonjour Kommunikation. Pidgin meldete Unable to send the message, the conversation couldn't be started. obwohl mein Gesprächspartner aufgeführt war. Die Umstände waren etwas schwer zu reproduzieren - mit einigen Rechnern funktionierte es, mit anderen nicht. Und genau das half mir auch eine "Lösung" zu finden: Wurde die Kommunikation von einem Rechner aus initiiert, bei dem ipv6 deaktiviert war, funktionierte das ganze. Sonst nicht.

Unter der Haube kommt "avahi" zum Einsatz - übrigens auch wenn es um remote Desktop Verbindungen geht. Hier hatte ich nämlich vergleichbare Probleme. Um das Bonjour und Remote-Desktop Problem zu loesen habe ich in der /etc/avahi/avahi-daemon.conf die Einstellung use-ipv6=yes auf use-ipv6=no geändert. Danach noch schnell den Avahi Dienst neu starten, und die  Probleme sind behoben. Pidgin selber wird in der nächsten Version auch einen Bugfix für dies Problem beinhalten, solange wollte ich aber nicht warten.

WLAN deauthenticating / denied association (code=17)

5 March 2011

Lange Suche, kleine Ursache: Wenn man sich mit einem Linux Rechner nicht mit einem Linksys / Cisco WLAN Router verbinden kann, und dabei Meldungen wie z.B.

NetworkManager[1036]: (wlan0): supplicant connection state: associating -> disconnected
NetworkManager[1036]: (wlan0): supplicant connection state: disconnected -> scanning
wpa_supplicant[1234]: Trying to associate with 00:14:bf:29:c4:23 (SSID='sforce-wpa' freq=2447 MHz)
NetworkManager[1036]: (wlan0): supplicant connection state: scanning -> associating
kernel: [ 417.694909] wlan0: authenticate with 00:14:bf:29:c4:23 (try 1)
kernel: [ 417.696781] wlan0: authenticated
kernel: [ 417.697518] wlan0: associate with 00:14:bf:29:c4:23 (try 1)
kernel: [ 417.700259] wlan0: RX AssocResp from 00:14:bf:29:c4:23 (capab=0x431 status=17 aid=0)
kernel: [ 417.700267] wlan0: 00:14:bf:29:c4:23 denied association (code=17)
kernel: [ 417.700297] wlan0: deauthenticating from 00:14:bf:29:c4:23 by local choice (reason=3)

auftauchen, dann handelt es sich um folgende Phänomen: Der Router ist der Meinung, dass er voll ist, und bittet den Client, sich mit einem anderen WLAN Access Point zu verbinden.

Windows Rechner ignorieren das, und verbinden sich dennoch mit dem Access Point, während Linux - in diesem Fall ein mit Ubuntu Maverick ausgestatteter Thinkpad - der Bitte Folge leistet. Er bricht den Verbindungsaufbau mit dem Router bzw. WLAN Access Point ab.

Leider ist davon in der GUI von Ubuntu (Network Manager) nichts zu sehen, sondern es dauert einfach sehr lange, bis erneut der Dialog zur Eingabe des WLAN Passwort auftaucht. Ein Blick in "dmesg" oder die Protokolldateien offenbart dann das Problem.

In meinem Fall ist der Router ein Linksys WRT mit Tomato Firmware - hier habe ich dann einfach die Anzahl der erlaubten Clients erhöht.

Glassfish 3.1 und httpOnly Session Cookie

4 March 2011

Wie bereits in meinem anderen Eintrag zu Glassfish 3.1 beschrieben, ist seit der Implementierung der Servlet 3.0 Spezifikation in Glassfish 3.1 der Session Cookie standardmäßig auf "httpOnly" gesetzt - dies kann Probleme mit einigen JavaScript Frameworks verursachen.

In dem web.xml Deploymentdescriptor kann dies umkonfiguriert werden, im glassfish-web.xml Descriptor ist dafür leider keine Möglichkeit vorgesehen. Weblogic, auch von Oracle mit BEA zugekauft, verhält sich dabei genauso, auch hier ist der Session Cookie auf httpOnly gesetzt - kann jedoch über den Weblogic spezifischen Deployment Descriptor unabhängig von der web.xml umkonfiguriert werden.

Und Glassfish 3.1 unterstützt nun auch ein Subset des Weblogic Deployment Descriptors um Weblogic kompatibel zu sein. (Vermutlich ist dies auch ein Grund, aus dem die Cookies httpOnly sind, um mit Weblogic konform zu sein.) Auch wenn es komisch ist, dass Glassfish selber keine Möglichkeit vorsieht das Verhalten im eigenen Deployment Deskriptor zu konfigurieren - über den Umweg des Weblogic spezifischen Descriptors geht es dann: <?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app">
<session-descriptor>
<cookie-http-only>false</cookie-http-only>
</session-descriptor>
</weblogic-web-app>

Glassfish 3.1: Probleme mit DWR 2 (und mehr)

28 February 2011

Oracle hat heute den Glassfish 3.1 freigegeben - gleichzeitig als Open Source und als Oracle Glassfish Edition. Es gibt eine Menge neues, und dazu gehören auch neue Probleme.

Ich verwende Glassfish schon seit geraumer Zeit um mittels "Continuous Deployment" für aktuell entwickelte Anwendungen eine separate Umgebung zu haben, in der ich und Kollegen testen können. Das ganze funktioniert mittels eine CI-Servers (Hudson Jenkins in diesem Fall), Maven und einem Deploy Plugin.

Auch mit Glassfish 3.1 funktionierte das Deployment prima - also hier war kein Update von Jenkins oder dem Deploy Plugin erforderlich. Auch die Anwendung startete - jedoch funktionierte nichts. Exceptions über ungültige Sessions gab es, auch Log-Einträge vom hier für Ajax eingesetzten DWR (Direct Web Remoting) 2011-02-28 18:57:13,037 [http-thread-pool-8090(2)] ERROR o.d.dwrp.Batch - A request has been denied as a potential CSRF attack.
2011-02-28 19:03:02,105 [http-thread-pool-8090(5)] ERROR o.d.dwrp.Batch - A request has been denied as a potential CSRF attack.
Dank Firebug etwas schlauem Rumraten und Probieren fand ich dann heraus: Glassfish 3.1 setzt Session Cookies per Default auf "HTTP Only". Dazu gibt es bereits ein Ticket im Glassfish Tracker: GLASSFISH-15730

Es gibt nun mehrere Möglichkeiten für die nötige Kompatibilität mit Bestandsanwendungen zu sorgen:

Wird man die Anwendung zukünftig immer in einem Servlet 3.0 kompatiblen Container deployen, so kann man in der web.xml das Verhalten umkonfigurieren:

<web-app>
  <session-config>
    <cookie-config>
      <http-only>true</http-only>
    </cookie-config>
  </session-config>
</web-app>
Alternativ kann man bei DWR den CSRF Check deaktivieren, wovon ich jedoch abraten würde:
<servlet>
  <servlet-name>dwr-invoker</servlet-name>
  <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
  <init-param>
    <param-name>crossDomainSessionSecurity</param-name>
    <param-value>false</param-value>
  </init-param>
</servlet>
Die letzte Möglichkeit ist - in diesem Fall - auf DWR 3 umzustellen, hier wurde das Problem grundsätzlich gelöst, so dass nicht mehr per JavaScript auf den Session Cookie zugegriffen werden muss. (Siehe DWR-26) Leider gibt es von DWR 3 bisher noch kein Release, sondern lediglich vorab-Versionen.

Das Problem tritt übrigens auch mit Tomcat 7 auf, und nicht nur mit Glassfish 3.1 - ich frage mich, ob dies Verhalten am Ende sogar in der Servlet 3 Spezifikation vorgegeben ist.
Natürlich betrifft dies nicht ausschließlich DWR, sondern auch andere Anwendungen, die per JavaScript auf den Session Cookie zugreifen wollen/müssen.

Jetty org.eclipse.jetty.io.EofException / Connection closed

17 February 2011

Bei der Umstellung von Jetty 6 zu Jetty 7 gab es (wie bereits geschildert) das eine oder andere an Überraschungsmomenten. So auch bei einem länger laufenden Request ( Fileupload anschließendes Parsen und Datenbank Updates die sich einige Minuten hinziehen können).

Die saubere Lösung wäre hier natürlich dem Nutzer eine Art Fortschritts-Anzeige zu präsentieren. Da die Funktion jedoch so bereits getestet ist, und auch kein Umbau geplant war, sollte es so bleiben. Lediglich Jetty hat hier (mal wieder) einen Strich durch die Rechnung gemacht: Geschlossene Verbindungen die mit org.eclipse.jetty.io.EofException und vielen hässlichen Stacktraces kommentiert wurden. Erst hatte ich die Applikation in Verdacht.

Dann den Browser - macht der Browser vielleicht die Verbindung zu, wird der Socket nur solange wie "keep-alive" erlaubt ist offen gehalten? Mit etwas wireshark / tcpdump konnte ich dann beweisen: Es war Jetty. Der Server schloss die Verbindung bevor der Prozess fertig war.

Zum Glück kann man aber den idle Timeout von Jetty konfigurieren, das ist die Zeit, in der eine Verbindung ohne Fortschritt fortbestehen darf. (Fortschritt wäre hier ein gesendetes oder empfangenes Byte.) Hier kann man noch gut in die Falle tappen, dass die Zeit in Milisekunden angegeben werden muss - lediglich der verdeckte Hinweis, dass der Wert "grob gesagt" in den Parameter für Socket.setSoTimeout(int) übersetzt wird, bringt einen hier auf die Spur.

Für das Jetty Maven Plugin sieht das dann so aus: <configuration>
<connectors>
<connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>8080</port>
<maxIdleTime>600000</maxIdleTime> <!-- 10 minutes in milliseconds! -->
<lowResourcesMaxIdleTime>600000</lowResourcesMaxIdleTime>
</connector>
</connectors>
</configuration>

Datenrettung mit Ubuntu

10 February 2011

So einfach kann Datenrettung sein: Meine Mutter hat auf einer Digitalkamera Bilder gehabt, die ihr sehr am Herzen liegen. Leider wurden die Fotos von der Digicam irgendwie gelöscht - und der Frust sehr groß.

Ich hab mir die Speicherkarte der Kamera geschnappt, diese mit einem USB Kartenleser an einen Ubuntu Rechner gehängt, und mittels "dd" ein Abbild der Karte gemacht: dd if=/dev/sdc of=~/Desktop/rettung.img bs=8192 Das ganze dauerte eine Weile, da es sich um eine 32 Gigabyte Speicherkarte handelte. Nun konnte ich gefahrlos auf dem Abbild arbeiten - soweit mir bekannt löschen Kameras die Fotos nicht sofort, sondern geben, wie bei Dateisystem im Computer, den Speicher lediglich zur Wiederverwendung frei. Somit sah ich gute Chancen auf einer erfolgreiche Datenrettung mit Bordmitteln.

Nachdem das Abbild erstellt war, habe ich mit dem Programm "photorec" das Abbild durchsuchen lassen (ggf. das Paket testdisk installieren, wenn photorec noch nicht verhanden ist): photorec rettung.img Nach einer geraumen Weile fanden sich dann die geretteten Bilder in dem von mir angegebenen Ordner. Ich liebe es, wenn ein Plan funktioniert.

Ubuntu: Fenster Größe anpassen

29 January 2011

Bei Ubuntu wurde der Bereich zum "Anfassen" der Fensterrahmen auf sagenhafte einen Pixel verkleinert - möchte man ein Fenster nun breiter ziehen muss man schon gut zielen.

Komfortabler geht das derzeit lediglich, wenn man über eine Maus mit drei Tasten verfügt (oder die mittlere Taste simuliert): Hält man die "Alt" Taste fest, kann man mit der mittleren Maustaste quasi beliebig ins Fenster klicken, und die Größe anpassen. Das ist am Anfang etwas ungewohnt, geht jedoch sogar noch schneller als erst den Fensterrahmen anzusteuern - selbst wenn dieser etwas breiter ist (oder wieder wird).

Maven, Jetty und der ExtraClasspath

28 January 2011

Es hat nur wenige Monate gedauert, aber dann konnte ich endlich einen besonders nervigen Fehler finden. Ich verwende Maven (wie fast immer) als Buildsystem und habe ein Projekt, dass Eclipse BIRT verwendet.
BIRT nutzt die Eclipse OSGi Plattform und daher werden beim Start einige Bilbiotheken benötigt. Nun gab es das Problem, dass dies im Tomcat nach einer kleinen Anpassung des Classpath prima funktionierte - nicht jedoch wenn ich das Maven Jetty Plugin verwendet habe. Trotz lt. Dokumentation korrekter Konfiguration über webAppConfig und extraClasspath Elemente.

Die Lösung war dann schließlich nicht mehr das maven-jetty-plugin in Version 6.1.2 sondern das - Achtung - jetty-maven-plugin in Version 7.2.1.v20101111 (die Versionnummer ist kein Witz) zu verwenden. Offenbar ein Jetty Bug - anders kann ich es mir nicht erklären.

Und so sieht dann die vollständige Konfiguration aus, die bei mir dann endlich auch zum Testen schnell und komfortabel funktioniert:

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>7.2.1.v20101111</version>
  <configuration>
    <webAppConfig>
      <extraClasspath>${BIRT_HOME}/lib/engineapi.jar;${BIRT_HOME}/lib/coreapi.jar; \
${BIRT_HOME}/lib/modelapi.jar;${BIRT_HOME}/lib/org.apache.commons.codec_1.3.0.v20100518-1140.jar; \
${BIRT_HOME}/lib/scriptapi.jar</extraClasspath>
    </webAppConfig>
  </configuration>
</plugin>

+4935188815303 - o2 fail

25 January 2011

Au weia, da hat sich o2 ja wieder nen echten FAIL geliefert: Ich hatte Anrufe von der Rufnummer +4935188815303 (also Deutschland 0351 88815303), aber immer nach 1x Klingeln, schneller als ich ans Handy gehen konnte, war der Anruf weg.

Dann hab ich mal zurückgerufen: Es ist eine O2 Nummer. Ich lande im O2 Callcenter - immerhin ist die 035188815303 ja per Festnetz Flatrate kostenlos erreichbar. Nach schier unendlichen "jetzt gleich aber wirklich tuuuut tuuuut leider doch alle im Gespräch bitte bleiben sie drann" geht ein Callcenter Agent ran. Ich möchte wissen, was O2 von mir möchte und warum man mir keine Chance gibt, ranzugehen. "Das ist ein Systemfehler, das System wählt zu kurz an". ACHSO! (Predictive Dailer anyone?)

Dann gebe ich meine Daten und und die gute Frau erklärt "o2 und Alice arbeiten jetzt zusammen und... " - "nein danke bloß nicht. Hab ich auch schon 2x gesagt, dass ich bereits DSL habe. Schönen Tag noch."

Maven, Jetty und Reloads: Session persistieren

22 January 2011

Entwickelt man mit Jetty als Servlet Container, so fällt der im Vergleich zu Glassfish relativ hohe Aufwand für Re-Deployments auf: Startet man Jetty per "mvn jetty:run" für jedes Deployment erneut, so dauert der Neustart erst mal relativ lange, dazu geht noch die gerade aktive Session verloren. So muss man sich gegebenenfalls nach jeder Änderung bzw. jedem Restart erneut anmelden.
Das kann man relativ einfach ändern: Jetty verfügt über die Möglichkeit die Session zu persistieren - dazu müssen natürlich Session Objekte serialisierbar sein, aber das sollten diese ja sowieso sein. (Stichwort "Session migration" und "Clustering")
Leider findet sich auf der Jetty Homepage lediglich eine Anleitung für Jetty 6 - Jetty 7 wird nun von Eclipse weiter entwickelt und damit gehen einige Änderungen einher, für die ich hier eine Beispielkonfiguration habe:

<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>7.2.1.v20101111</version>
<configuration>
  <webAppConfig>
    <sessionHandler implementation="org.eclipse.jetty.server.session.SessionHandler">
      <sessionManager implementation="org.eclipse.jetty.server.session.HashSessionManager">
      <storeDirectory>${basedir}/target/sessions/</storeDirectory>
    </sessionManager>
  </sessionHandler>
<contextPath>/${project.artifactId}</contextPath>
</webAppConfig>
<!--
<reload>automatic</reload>
<scanIntervalSeconds>2</scanIntervalSeconds>
<scanTargets>
<scanTarget>target/classes/</scanTarget>
</scanTargets>-->
</configuration>
</plugin>
Mit dieser Einstellung werden die Session Daten in dem Order "target/sessions" persistiert, und man kann bei einem Neustart dort weitermachen, wo man aufgehört hat.

Tipps zum Tastatur Layout

15 January 2011

Schon seit einem guten Jahr nutze ich das US Tastaturlayout unter Ubuntu als Standardlayout. Gerade zum Entwickeln konnte ich wegen der besseren Position von Semikolon und geschweiften Klammern schnell einen Produktivitätsgewinn feststellen.

Doch dann kamen auch die Rückschläge: Euro Zeichen, Paragraphenzeichen (§) und Umlaute sind nicht mehr verfügbar. Für Umlaute behelfen sich einige mit Unicode Eingabe, oder Copy-Paste-Vorlagen. Ich habe mir bisher damit geholfen, dass ich die Rechtschreibkorrektur einfach "ue" in "ü" habe umwandeln lassen. Hilft jedoch nicht z.B. beim "§"-Zeichen.

Und da habe ich jetzt das Feature "Compose Key" gefunden. Damit kann man - fast wie bei LaTeX - Buchstaben zusammensetzen. Dazu aktiviert man erstmal die Einstellung ein "Compose Key" auf der Tastatur zu haben, ich habe dazu die rechte Alt-Taste verwendet. (System->Preferences->Keyboard, Layout auswählen, "Options")

Anschließend kann man mittels <compose>-<u>, und <"> ein "ü" zusammensetzen. Das Paragraphenzeichen geht z.B. über <compose>-<s>, <o>

Patientenabzocke und Abmahnrisiko für Ärzte: 01805 Notfall "Service"

14 January 2011

Das sind Dinge, da versteh ich nicht, wie es dazu kommen kann. Wirklich nicht. Es geht um die Verbesserung des Notfalldienstes für gesetzlich (und privat) versicherte Patienten in Deutschland. Bisher ist es an mir vorbei gegangen, aber spätestens mit dieser Presseerklärung der Kassenärztlichen Vereinigung Westfalen Lippe (KVWL) ist wohl auch NRW dran: Statt bisher zum Ortstarif muss man eine 0180-5 Servicenummer anrufen, wenn man außerhalb der regulären Sprechstundenzeiten einen medizinischen Notfall hat. Der Vorteil: Die Rufnummer ist einheitlich, nicht mehr vom jeweiligen Ortsnetz abhängig.

Das war nicht immer so! Zumindest in Münster gab es verschiedene Rufnummern für die verschiedenen Bereiche, nämlich die "192 92". Die Vorwahl konnte man wählen oder es sein lassen. Was war da jetzt uneinheitlich? Eine kurze Google Suche erweckt auch den Anschein, als sei die "19292" relativ einheitlich verfügbar, lediglich bei manchen Gemeinden ist eine andere Rufnummer für die Fachrichtung zu wählen. Aber auch das ist nichts unmögliches - und wenn doch, wählt man eh besser die "112".


/
Copyright © 2007, 2008 everflux. Alle Rechte vorbehalten. All rights reserved.