Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/test/993-breakpoints/src/art/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 23 kB image not shown  

Quelle  Test993.java

  Sprache: JAVA
 

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


package art;

import java.lang.reflect.Executable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

import java.time.Duration;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.Stack;
import java.util.Vector;

import java.util.function.Supplier;

public class Test993 {

  public static final Breakpoint.Manager MANAGER = new Breakpoint.Manager();

  // A function we can use as a start breakpoint.
  public static void breakpoint() {
    return;
  }

  private static void privateBreakpoint() {
    return;
  }

  // An interface with a default method we can break on.
  static interface Breakable {
    public static void iBreakpoint() {
      return;
    }

    public default void breakit() {
      return;
    }
  }

  // A class that has a default method we breakpoint on.
  public static class TestClass1 implements Breakable {
    public TestClass1() {
      super();
    }
    public String toString() { return "TestClass1"; }
  }

  // A class that overrides a default method that we can breakpoint on and calls super.
  public static class TestClass1ext extends TestClass1 {
    public TestClass1ext() {
      super();
    }
    public String toString() { return "TestClass1Ext"; }
    public void breakit() {
      super.breakit();
    }
  }


  // A class that overrides a default method that we can breakpoint on.
  public static class TestClass2 implements Breakable {
    public String toString() { return "TestClass2"; }
    public void breakit() {
      return;
    }
  }

  // A class that overrides a default method that we can breakpoint on and calls super.
  public static class TestClass2ext extends TestClass2 {
    public String toString() { return "TestClass2ext"; }
    public void breakit() {
      super.breakit();
    }
  }

  // A class that overrides a default method and calls it directly with interface invoke-super
  public static class TestClass3 implements Breakable {
    public String toString() { return "TestClass3"; }
    public void breakit() {
      Breakable.super.breakit();
    }
  }

  // A class that overrides a default method that we can breakpoint on and calls super to a class
  // that uses interface-invoke-super.
  public static class TestClass3ext extends TestClass3 {
    public String toString() { return "TestClass3ext"; }
    public void breakit() {
      super.breakit();
    }
  }

  public static class TestClass4 {
    public String toString() { return "TestClass4"; }
    public void callPrivateMethod() {
      privateMethod();
    }
    private void privateMethod() {
      return;
    }
  }

  public static void notifyBreakpointReached(Thread thr, Executable e, long loc) {
    String line;
    if (e.getDeclaringClass().getPackage().equals(Test993.class.getPackage())) {
      line = Integer.valueOf(Breakpoint.locationToLine(e, loc)).toString();
    } else {
      line = "<NON-DETERMINISTIC>";
    }
    System.out.println("\t\t\tBreakpoint: " + e + " @ line=" + line);
  }

  public static interface ThrowRunnable extends Runnable {
    public default void run() {
      try {
        runThrow();
      } catch (Exception e) {
        throw new Error("Caught error while running " + this, e);
      }
    }
    public void runThrow() throws Exception;
  }

  public static class InvokeDirect implements Runnable {
    String msg;
    Runnable r;
    public InvokeDirect(String msg, Runnable r) {
      this.msg = msg;
      this.r = r;
    }
    @Override
    public void run() {
      System.out.println("\t\tInvoking \"" + msg + "\"");
      r.run();
    }
  }

  public static class InvokeReflect implements ThrowRunnable {
    Method m;
    Object this_arg;
    public InvokeReflect(Method m, Object this_arg) {
      this.m = m;
      this.this_arg = this_arg;
    }

    @Override
    public void runThrow() throws Exception {
      System.out.println("\t\tReflective invoking: " + m + " args: [this: " + this_arg + "]");
      m.invoke(this_arg);
    }
  }

  public static class InvokeNative implements Runnable {
    Method m;
    Object this_arg;
    public InvokeNative(Method m, Object this_arg) {
      this.m = m;
      this.this_arg = this_arg;
    }

    @Override
    public void run() {
      System.out.println("\t\tNative invoking: " + m + " args: [this: " + this_arg + "]");
      invokeNative(m, m.getDeclaringClass(), this_arg);
    }
  }

  public static native void invokeNative(Method m, Class<?> clazz, Object thizz);

  public static class InvokeNativeBool implements Runnable {
    Method m;
    Object this_arg;
    public InvokeNativeBool(Method m, Object this_arg) {
      this.m = m;
      this.this_arg = this_arg;
    }

    @Override
    public void run() {
      System.out.println("\t\tNative invoking: " + m + " args: [this: " + this_arg + "]");
      invokeNativeBool(m, m.getDeclaringClass(), this_arg);
    }
  }

  public static native void invokeNativeBool(Method m, Class<?> clazz, Object thizz);

  public static class InvokeNativeObject implements Runnable {
    Method m;
    Object this_arg;
    public InvokeNativeObject(Method m, Object this_arg) {
      this.m = m;
      this.this_arg = this_arg;
    }

    @Override
    public void run() {
      System.out.println("\t\tNative invoking: " + m + " args: [this: " + this_arg + "]");
      invokeNativeObject(m, m.getDeclaringClass(), this_arg);
    }
  }

  public static native void invokeNativeObject(Method m, Class<?> clazz, Object thizz);

  public static class InvokeNativeLong implements Runnable {
    Method m;
    Object this_arg;
    public InvokeNativeLong(Method m, Object this_arg) {
      this.m = m;
      this.this_arg = this_arg;
    }

    @Override
    public void run() {
      System.out.println("\t\tNative invoking: " + m + " args: [this: " + this_arg + "]");
      invokeNativeLong(m, m.getDeclaringClass(), this_arg);
    }
  }

  public static native void invokeNativeLong(Method m, Class<?> clazz, Object thizz);

  public static class ConstructDirect implements Runnable {
    String msg;
    Supplier<Object> s;
    public ConstructDirect(String msg, Supplier<Object> s) {
      this.msg = msg;
      this.s = s;
    }

    @Override
    public void run() {
      System.out.println("\t\tConstructing: " + msg);
      System.out.println("\t\t\tCreated: " + s.get());
    }
  }

  public static class ConstructReflect implements ThrowRunnable {
    Constructor<?> m;
    public ConstructReflect(Constructor<?> m) {
      this.m = m;
    }

    @Override
    public void runThrow() throws Exception {
      System.out.println("\t\tReflective constructor: " + m);
      System.out.println("\t\t\tCreated: " + m.newInstance());
    }
  }

  public static class ConstructNative implements Runnable {
    Constructor<?> m;
    Class type;
    public ConstructNative(Constructor<?> m) {
      this.m = m;
      this.type = m.getDeclaringClass();
    }

    @Override
    public void run() {
      System.out.println("\t\tNative constructor: " + m + ", type: " + type);
      System.out.println("\t\t\tCreated: " + constructNative(m, type));
    }
  }

  public static native Object constructNative(Constructor m, Class<?> clazz);

  private static <T> List<List<T>> combinations(List<T> items, int len) {
    if (len > items.size()) {
      throw new Error("Bad length" + len + " " + items);
    }
    if (len == 1) {
      List<List<T>> out = new ArrayList<>();
      for (T t : items) {
        out.add(Arrays.asList(t));
      }
      return out;
    }
    List<List<T>> out = new ArrayList<>();
    for (int rem = 0; rem <= items.size() - len; rem++) {
      for (List<T> others : combinations(items.subList(rem + 1, items.size()), len - 1)) {
        List<T> newone = new ArrayList<>();
        newone.add(items.get(rem));
        newone.addAll(others);
        out.add(newone);
      }
    }
    return out;
  }

  private static <T> List<List<T>> allCombinations(List<T> items) {
    List<List<T>> out = new ArrayList<List<T>>();
    out.add(new ArrayList<>());
    for (int i = 0; i < items.size(); i++) {
      out.addAll(combinations(items, i + 1));
    }
    return out;
  }

  private static Breakpoint.Manager.BP BP(Executable m) {
    return new Breakpoint.Manager.BP(m) {
      public String toString() {
        if (method.getDeclaringClass().getPackage().equals(Test993.class.getPackage())) {
          return super.toString();
        } else {
          return method.toString() + " @ <NON-DETERMINISTIC>";
        }
      }
    };
  }

  public static void run() throws Exception {
    run(false);
  }
  public static void run(boolean test_BCP_private) throws Exception {
    // Set up breakpoints
    Breakpoint.stopBreakpointWatch(Thread.currentThread());
    Breakpoint.startBreakpointWatch(
        Test993.class,
        Test993.class.getDeclaredMethod("notifyBreakpointReached",
          Thread.class, Executable.classLong.TYPE),
        Thread.currentThread());

    runMethodTests();
    runBCPMethodTests(test_BCP_private);
    runConstructorTests();

    Breakpoint.stopBreakpointWatch(Thread.currentThread());
  }

  public static void runConstructorTests() throws Exception {
    // The constructors we will be breaking on.
    Constructor<?> tc1_construct = TestClass1.class.getConstructor();
    Constructor<?> tc1ext_construct = TestClass1ext.class.getConstructor();

    Runnable[] tc1_constructors = new Runnable[] {
      new ConstructNative(tc1_construct),
      new ConstructReflect(tc1_construct),
      new ConstructDirect("new TestClass1()", TestClass1::new),
    };
    Breakpoint.Manager.BP[] tc1_bps = new Breakpoint.Manager.BP[] {
      BP(tc1_construct),
    };
    runTestGroups("TestClass1 constructor", tc1_constructors, tc1_bps);

    Runnable[] tc1ext_constructors = new Runnable[] {
      new ConstructNative(tc1ext_construct),
      new ConstructReflect(tc1ext_construct),
      new ConstructDirect("new TestClass1ext()", TestClass1ext::new),
    };
    Breakpoint.Manager.BP[] tc1ext_bps = new Breakpoint.Manager.BP[] {
      BP(tc1_construct), BP(tc1ext_construct),
    };
    runTestGroups("TestClass1ext constructor", tc1ext_constructors, tc1ext_bps);
  }

  // These test to make sure we are able to break on functions that might have been quickened or
  // inlined from the boot-image. These were all chosen for being in the bootclasspath, not being
  // long enough to prevent inlining, and not being used for the testing framework.
  @SuppressWarnings("OptionalOfRedundantMethod")
  public static void runBCPMethodTests(boolean test_BCP_private) throws Exception {
    // The methods we will be breaking on.
    Method bcp_private_method =
        test_BCP_private ? Duration.class.getDeclaredMethod("toBigDecimalSeconds") : null;
    Method bcp_virtual_method = Optional.class.getDeclaredMethod("isPresent");
    Method bcp_static_method = Optional.class.getDeclaredMethod("empty");
    Method bcp_private_static_method =
        test_BCP_private ? Random.class.getDeclaredMethod("seedUniquifier") : null;

    // Some constructors we will break on.
    Constructor<?> bcp_stack_constructor = Stack.class.getConstructor();
    Constructor<?> bcp_vector_constructor = Vector.class.getConstructor();
    if (!(Vector.class.isAssignableFrom(Stack.class))) {
      throw new Error("Expected Stack to extend Vector!");
    }

    // BCP constructors.
    Runnable[] vector_constructors = new Runnable[] {
      new ConstructNative(bcp_vector_constructor),
      new ConstructReflect(bcp_vector_constructor),
      new ConstructDirect("new Vector()", Vector::new),
    };
    Breakpoint.Manager.BP[] vector_breakpoints = new Breakpoint.Manager.BP[] {
      BP(bcp_vector_constructor),
    };
    runTestGroups("Vector constructor", vector_constructors, vector_breakpoints);

    Runnable[] stack_constructors = new Runnable[] {
      new ConstructNative(bcp_stack_constructor),
      new ConstructReflect(bcp_stack_constructor),
      new ConstructDirect("new Stack()", Stack::new),
    };
    Breakpoint.Manager.BP[] stack_breakpoints = new Breakpoint.Manager.BP[] {
      BP(bcp_stack_constructor), BP(bcp_vector_constructor),
    };
    runTestGroups("Stack constructor", stack_constructors, stack_breakpoints);

    // Static function
    Runnable[] static_invokes = new Runnable[] {
      new InvokeNativeObject(bcp_static_method, null),

      new InvokeReflect(bcp_static_method, null),

      new InvokeDirect("Optional::empty", () -> { Optional.empty(); }),
    };
    Breakpoint.Manager.BP[] static_breakpoints = new Breakpoint.Manager.BP[] {
      BP(bcp_static_method)
    };
    runTestGroups("bcp static invoke", static_invokes, static_breakpoints);

    // Static private class function
    if (test_BCP_private) {
      Runnable[] private_static_invokes = new Runnable[] {
        new InvokeNativeLong(bcp_private_static_method, null),

        new InvokeDirect("Random::seedUniquifier", () -> { new Random(); }),
      };
      Breakpoint.Manager.BP[] private_static_breakpoints = new Breakpoint.Manager.BP[] {
        BP(bcp_private_static_method)
      };
      runTestGroups("bcp private static invoke", private_static_invokes, private_static_breakpoints);
    }

    // private class method
    if (test_BCP_private) {
      Duration test_duration = Duration.ofDays(14);
      Runnable[] private_invokes = new Runnable[] {
        new InvokeNativeObject(bcp_private_method, test_duration),

        new InvokeDirect("Duration::toBigDecimalSeconds", () -> { test_duration.multipliedBy(2); }),
      };
      Breakpoint.Manager.BP[] private_breakpoints = new Breakpoint.Manager.BP[] {
        BP(bcp_private_method)
      };
      runTestGroups("bcp private invoke", private_invokes, private_breakpoints);
    }

    // class method
    Runnable[] public_invokes = new Runnable[] {
      new InvokeNativeBool(bcp_virtual_method, Optional.of("test")),

      new InvokeReflect(bcp_virtual_method, Optional.of("test2")),

      new InvokeDirect("Optional::isPresent", () -> { Optional.of("test3").isPresent(); }),
    };
    Breakpoint.Manager.BP[] public_breakpoints = new Breakpoint.Manager.BP[] {
      BP(bcp_virtual_method)
    };
    runTestGroups("bcp invoke", public_invokes, public_breakpoints);
  }

  public static void runMethodTests() throws Exception {
    // The methods we will be breaking on.
    Method breakpoint_method = Test993.class.getDeclaredMethod("breakpoint");
    Method private_breakpoint_method = Test993.class.getDeclaredMethod("privateBreakpoint");
    Method i_breakpoint_method = Breakable.class.getDeclaredMethod("iBreakpoint");
    Method breakit_method = Breakable.class.getDeclaredMethod("breakit");
    Method breakit_method_tc1ext = TestClass1ext.class.getDeclaredMethod("breakit");
    Method breakit_method_tc2 = TestClass2.class.getDeclaredMethod("breakit");
    Method breakit_method_tc2ext = TestClass2ext.class.getDeclaredMethod("breakit");
    Method breakit_method_tc3 = TestClass3.class.getDeclaredMethod("breakit");
    Method breakit_method_tc3ext = TestClass3ext.class.getDeclaredMethod("breakit");
    Method private_method = TestClass4.class.getDeclaredMethod("privateMethod");

    // Static class function
    Runnable[] static_invokes = new Runnable[] {
      new InvokeNative(breakpoint_method, null),

      new InvokeReflect(breakpoint_method, null),

      new InvokeDirect("Test993::breakpoint", Test993::breakpoint),
    };
    Breakpoint.Manager.BP[] static_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakpoint_method)
    };
    runTestGroups("static invoke", static_invokes, static_breakpoints);

    // Static private class function
    Runnable[] private_static_invokes = new Runnable[] {
      new InvokeNative(private_breakpoint_method, null),

      new InvokeDirect("Test993::privateBreakpoint", Test993::privateBreakpoint),
    };
    Breakpoint.Manager.BP[] private_static_breakpoints = new Breakpoint.Manager.BP[] {
      BP(private_breakpoint_method)
    };
    runTestGroups("private static invoke", private_static_invokes, private_static_breakpoints);

    // Static interface function.
    Runnable[] i_static_invokes = new Runnable[] {
      new InvokeNative(i_breakpoint_method, null),

      new InvokeReflect(i_breakpoint_method, null),

      new InvokeDirect("Breakable::iBreakpoint", Breakable::iBreakpoint),
    };
    Breakpoint.Manager.BP[] i_static_breakpoints = new Breakpoint.Manager.BP[] {
      BP(i_breakpoint_method)
    };
    runTestGroups("interface static invoke", i_static_invokes, i_static_breakpoints);

    // Call default method through a class.
    Runnable[] tc1_invokes = new Runnable[] {
      new InvokeNative(breakit_method, new TestClass1()),

      new InvokeReflect(breakit_method, new TestClass1()),

      new InvokeDirect("((Breakable)new TestClass1()).breakit()",
                  () -> ((Breakable)new TestClass1()).breakit()),
      new InvokeDirect("new TestClass1().breakit()",
                  () -> new TestClass1().breakit()),
    };
    Breakpoint.Manager.BP[] tc1_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakit_method)
    };
    runTestGroups("TestClass1 invokes", tc1_invokes, tc1_breakpoints);

    // Call default method through an override and normal invoke-super
    Runnable[] tc1ext_invokes = new Runnable[] {
      new InvokeNative(breakit_method, new TestClass1ext()),
      new InvokeNative(breakit_method_tc1ext, new TestClass1ext()),

      new InvokeReflect(breakit_method, new TestClass1ext()),
      new InvokeReflect(breakit_method_tc1ext, new TestClass1ext()),

      new InvokeDirect("((Breakable)new TestClass1ext()).breakit()",
                  () -> ((Breakable)new TestClass1ext()).breakit()),
      new InvokeDirect("((TestClass1)new TestClass1ext()).breakit()",
                  () -> ((TestClass1)new TestClass1ext()).breakit()),
      new InvokeDirect("new TestClass1ext().breakit()",
                  () -> new TestClass1ext().breakit()),
    };
    Breakpoint.Manager.BP[] tc1ext_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakit_method), BP(breakit_method_tc1ext)
    };
    runTestGroups("TestClass1ext invokes", tc1ext_invokes, tc1ext_breakpoints);

    // Override default/interface method.
    Runnable[] tc2_invokes = new Runnable[] {
      new InvokeNative(breakit_method, new TestClass2()),
      new InvokeNative(breakit_method_tc2, new TestClass2()),

      new InvokeReflect(breakit_method, new TestClass2()),
      new InvokeReflect(breakit_method_tc2, new TestClass2()),

      new InvokeDirect("((Breakable)new TestClass2()).breakit()",
                  () -> ((Breakable)new TestClass2()).breakit()),
      new InvokeDirect("new TestClass2().breakit()",
                  () -> new TestClass2().breakit()),
    };
    Breakpoint.Manager.BP[] tc2_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakit_method), BP(breakit_method_tc2)
    };
    runTestGroups("TestClass2 invokes", tc2_invokes, tc2_breakpoints);

    // Call overridden method using invoke-super
    Runnable[] tc2ext_invokes = new Runnable[] {
      new InvokeNative(breakit_method, new TestClass2ext()),
      new InvokeNative(breakit_method_tc2, new TestClass2ext()),
      new InvokeNative(breakit_method_tc2ext, new TestClass2ext()),

      new InvokeReflect(breakit_method, new TestClass2ext()),
      new InvokeReflect(breakit_method_tc2, new TestClass2ext()),
      new InvokeReflect(breakit_method_tc2ext, new TestClass2ext()),

      new InvokeDirect("((Breakable)new TestClass2ext()).breakit()",
                  () -> ((Breakable)new TestClass2ext()).breakit()),
      new InvokeDirect("((TestClass2)new TestClass2ext()).breakit()",
                  () -> ((TestClass2)new TestClass2ext()).breakit()),
      new InvokeDirect("new TestClass2ext().breakit())",
                  () -> new TestClass2ext().breakit()),
    };
    Breakpoint.Manager.BP[] tc2ext_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakit_method), BP(breakit_method_tc2), BP(breakit_method_tc2ext)
    };
    runTestGroups("TestClass2ext invokes", tc2ext_invokes, tc2ext_breakpoints);

    // Override default method and call it using interface-invoke-super
    Runnable[] tc3_invokes = new Runnable[] {
      new InvokeNative(breakit_method, new TestClass3()),
      new InvokeNative(breakit_method_tc3, new TestClass3()),

      new InvokeReflect(breakit_method, new TestClass3()),
      new InvokeReflect(breakit_method_tc3, new TestClass3()),

      new InvokeDirect("((Breakable)new TestClass3()).breakit()",
                  () -> ((Breakable)new TestClass3()).breakit()),
      new InvokeDirect("new TestClass3().breakit())",
                  () -> new TestClass3().breakit()),
    };
    Breakpoint.Manager.BP[] tc3_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakit_method), BP(breakit_method_tc3)
    };
    runTestGroups("TestClass3 invokes", tc3_invokes, tc3_breakpoints);

    // Call overridden method using invoke-super
    Runnable[] tc3ext_invokes = new Runnable[] {
      new InvokeNative(breakit_method, new TestClass3ext()),
      new InvokeNative(breakit_method_tc3, new TestClass3ext()),
      new InvokeNative(breakit_method_tc3ext, new TestClass3ext()),

      new InvokeReflect(breakit_method, new TestClass3ext()),
      new InvokeReflect(breakit_method_tc3, new TestClass3ext()),
      new InvokeReflect(breakit_method_tc3ext, new TestClass3ext()),

      new InvokeDirect("((Breakable)new TestClass3ext()).breakit()",
                  () -> ((Breakable)new TestClass3ext()).breakit()),
      new InvokeDirect("((TestClass3)new TestClass3ext()).breakit()",
                  () -> ((TestClass3)new TestClass3ext()).breakit()),
      new InvokeDirect("new TestClass3ext().breakit())",
                  () -> new TestClass3ext().breakit()),
    };
    Breakpoint.Manager.BP[] tc3ext_breakpoints = new Breakpoint.Manager.BP[] {
      BP(breakit_method), BP(breakit_method_tc3), BP(breakit_method_tc3ext)
    };
    runTestGroups("TestClass3ext invokes", tc3ext_invokes, tc3ext_breakpoints);

    // private instance method.
    Runnable[] private_instance_invokes = new Runnable[] {
      new InvokeNative(private_method, new TestClass4()),

      new InvokeDirect("new TestClass4().callPrivateMethod()",
                  () -> new TestClass4().callPrivateMethod()),
    };
    Breakpoint.Manager.BP[] private_instance_breakpoints = new Breakpoint.Manager.BP[] {
      BP(private_method)
    };
    runTestGroups(
        "private instance invoke", private_instance_invokes, private_instance_breakpoints);
  }

  private static void runTestGroups(String name,
                                    Runnable[] invokes,
                                    Breakpoint.Manager.BP[] breakpoints) throws Exception {
    System.out.println("Running " + name);
    for (List<Breakpoint.Manager.BP> bps : allCombinations(Arrays.asList(breakpoints))) {
      System.out.println("\tBreaking on " + bps);
      for (Runnable test : invokes) {
        MANAGER.clearAllBreakpoints();
        MANAGER.setBreakpoints(bps.toArray(new Breakpoint.Manager.BP[0]));
        test.run();
      }
    }
  }
}

Messung V0.5 in Prozent
C=90 H=90 G=90

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.