// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/cupertino.dart';

void main() {
  // Generic reference variables.
  BuildContext context;
  RenderObjectWidget renderObjectWidget;
  RenderObject renderObject;
  Object object;

  // Change made in https://github.com/flutter/flutter/pull/41859
  CupertinoTextThemeData themeData = CupertinoTextThemeData(

  );
  themeData.copyWith();
  themeData = CupertinoTextThemeData(error: '');
  themeData.copyWith(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/44189
  const Element element = Element(myWidget);
  element.dependOnInheritedElement(ancestor);
  element.dependOnInheritedWidgetOfExactType<targetType>();
  element.getElementForInheritedWidgetOfExactType<targetType>();
  element.findAncestorWidgetOfExactType<targetType>();
  element.findAncestorStateOfType<targetType>();
  element.findRootAncestorStateOfType<targetType>();
  element.findAncestorRenderObjectOfType<targetType>();

  // Changes made in https://github.com/flutter/flutter/pull/45941 and https://github.com/flutter/flutter/pull/83843
  final WidgetsBinding binding = WidgetsBinding.instance;
  binding.deferFirstFrame();
  binding.allowFirstFrame();

  // Changes made in https://github.com/flutter/flutter/pull/44189
  const StatefulElement statefulElement = StatefulElement(myWidget);
  statefulElement.dependOnInheritedElement(ancestor);

  // Changes made in https://github.com/flutter/flutter/pull/44189
  const BuildContext buildContext = Element(myWidget);
  buildContext.dependOnInheritedElement(ancestor);
  buildContext.dependOnInheritedWidgetOfExactType<targetType>();
  buildContext.getElementForInheritedWidgetOfExactType<targetType>();
  buildContext.findAncestorWidgetOfExactType<targetType>();
  buildContext.findAncestorStateOfType<targetType>();
  buildContext.findRootAncestorStateOfType<targetType>();
  buildContext.findAncestorRenderObjectOfType<targetType>();

  // Changes made in https://github.com/flutter/flutter/pull/66305
  const Stack stack = Stack(clipBehavior: Clip.none);
  const Stack stack = Stack(clipBehavior: Clip.hardEdge);
  const Stack stack = Stack(error: '');
  final behavior = stack.clipBehavior;

  // Changes made in https://github.com/flutter/flutter/pull/61648
  const Form form = Form(autovalidateMode: AutovalidateMode.always);
  const Form form = Form(autovalidateMode: AutovalidateMode.disabled);
  const Form form = Form(error: '');
  final autoMode = form.autovalidateMode;

  // Changes made in https://github.com/flutter/flutter/pull/61648
  const FormField formField = FormField(autovalidateMode: AutovalidateMode.always);
  const FormField formField = FormField(autovalidateMode: AutovalidateMode.disabled);
  const FormField formField = FormField(error: '');
  final autoMode = formField.autovalidateMode;

  // Changes made in https://github.com/flutter/flutter/pull/68736
  MediaQuery.maybeOf(context);
  MediaQuery.of(context);
  MediaQuery.of(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/70726
  Navigator.maybeOf(context);
  Navigator.of(context);
  Navigator.of(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/68910
  Router.maybeOf(context);
  Router.of(context);
  Router.of(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/68911
  Localizations.maybeLocaleOf(context);
  Localizations.localeOf(context);
  Localizations.localeOf(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/68917
  FocusTraversalOrder.maybeOf(context);
  FocusTraversalOrder.of(context);
  FocusTraversalOrder.of(error: '');
  FocusTraversalGroup.of(error: '');
  FocusTraversalGroup.maybeOf(context);
  FocusTraversalGroup.of(context);
  Focus.maybeOf(context);
  Focus.of(context);
  Focus.of(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/68921
  Shortcuts.maybeOf(context);
  Shortcuts.of(context);
  Shortcuts.of(error: '');
  Actions.find(error: '');
  Actions.maybeFind(context);
  Actions.find(context);
  Actions.handler(context);
  Actions.handler(context);
  Actions.handler(error: '');
  Actions.invoke(error: '');
  Actions.maybeInvoke(context);
  Actions.invoke(context);

  // Changes made in https://github.com/flutter/flutter/pull/68925
  AnimatedList.maybeOf(context);
  AnimatedList.of(context);
  AnimatedList.of(error: '');
  SliverAnimatedList.of(error: '');
  SliverAnimatedList.maybeOf(context);
  SliverAnimatedList.of(context);

  // Changes made in https://github.com/flutter/flutter/pull/68905
  CupertinoDynamicColor.maybeResolve(Color(0), context);
  CupertinoDynamicColor.resolve(Color(0), context);
  CupertinoDynamicColor.resolve(error: '');
  CupertinoDynamicColor.resolveFrom(error: '');
  CupertinoDynamicColor.resolveFrom(context);
  CupertinoDynamicColor.resolveFrom(context);
  CupertinoUserInterfaceLevel.maybeOf(context);
  CupertinoUserInterfaceLevel.of(context);
  CupertinoUserInterfaceLevel.of(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/68736
  CupertinoTheme.maybeBrightnessOf(context);
  CupertinoTheme.brightnessOf(context);
  CupertinoTheme.brightnessOf(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/68905
  CupertinoThemeData.resolveFrom(context);
  CupertinoThemeData.resolveFrom(context);
  CupertinoThemeData.resolveFrom(error: '');
  NoDefaultCupertinoThemeData.resolveFrom(error: '');
  NoDefaultCupertinoThemeData.resolveFrom(context);
  NoDefaultCupertinoThemeData.resolveFrom(context);
  CupertinoTextThemeData.resolveFrom(context);
  CupertinoTextThemeData.resolveFrom(context);
  CupertinoTextThemeData.resolveFrom(error: '');

  // Changes made in https://github.com/flutter/flutter/pull/72043
  CupertinoTextField(maxLengthEnforcement: MaxLengthEnforcement.enforce);
  CupertinoTextField(maxLengthEnforcement: MaxLengthEnforcement.none);
  CupertinoTextField(error: '');
  CupertinoTextField.borderless(error: '');
  CupertinoTextField.borderless(maxLengthEnforcement: MaxLengthEnforcement.enforce);
  CupertinoTextField.borderless(maxLengthEnforcement: MaxLengthEnforcement.none);
  final CupertinoTextField textField;
  textField.maxLengthEnforcement;

  // Changes made in https://github.com/flutter/flutter/pull/59127
  const BottomNavigationBarItem bottomNavigationBarItem =
      BottomNavigationBarItem(label: myTitle);
  const BottomNavigationBarItem bottomNavigationBarItem =
      BottomNavigationBarItem();
  const BottomNavigationBarItem bottomNavigationBarItem =
      BottomNavigationBarItem(error: '');
  bottomNavigationBarItem.label;

  // Changes made in https://github.com/flutter/flutter/pull/79160
  Draggable draggable = Draggable();
  draggable = Draggable(error: '');
  draggable = Draggable(dragAnchorStrategy: childDragAnchorStrategy);
  draggable = Draggable(dragAnchorStrategy: pointerDragAnchorStrategy);
  draggable.dragAnchorStrategy;

  // Changes made in https://github.com/flutter/flutter/pull/79160
  LongPressDraggable longPressDraggable = LongPressDraggable();
  longPressDraggable = LongPressDraggable(error: '');
  longPressDraggable = LongPressDraggable(dragAnchorStrategy: childDragAnchorStrategy);
  longPressDraggable = LongPressDraggable(dragAnchorStrategy: pointerDragAnchorStrategy);
  longPressDraggable.dragAnchorStrategy;

  // Changes made in https://github.com/flutter/flutter/pull/64254
  final LeafRenderObjectElement leafElement = LeafRenderObjectElement();
  leafElement.insertRenderObjectChild(renderObject, object);
  leafElement.moveRenderObjectChild(renderObject, object);
  leafElement.removeRenderObjectChild(renderObject);
  final ListWheelElement listWheelElement = ListWheelElement();
  listWheelElement.insertRenderObjectChild(renderObject, object);
  listWheelElement.moveRenderObjectChild(renderObject, object);
  listWheelElement.removeRenderObjectChild(renderObject);
  final MultiChildRenderObjectElement multiChildRenderObjectElement =
      MultiChildRenderObjectElement();
  multiChildRenderObjectElement.insertRenderObjectChild(renderObject, object);
  multiChildRenderObjectElement.moveRenderObjectChild(renderObject, object);
  multiChildRenderObjectElement.removeRenderObjectChild(renderObject);
  final SingleChildRenderObjectElement singleChildRenderObjectElement =
      SingleChildRenderObjectElement();
  singleChildRenderObjectElement.insertRenderObjectChild(renderObject, object);
  singleChildRenderObjectElement.moveRenderObjectChild(renderObject, object);
  singleChildRenderObjectElement.removeRenderObjectChild(renderObject);
  final SliverMultiBoxAdaptorElement sliverMultiBoxAdaptorElement =
      SliverMultiBoxAdaptorElement();
  sliverMultiBoxAdaptorElement.insertRenderObjectChild(renderObject, object);
  sliverMultiBoxAdaptorElement.moveRenderObjectChild(renderObject, object);
  sliverMultiBoxAdaptorElement.removeRenderObjectChild(renderObject);
  final RenderObjectToWidgetElement renderObjectToWidgetElement =
      RenderObjectToWidgetElement(widget);
  renderObjectToWidgetElement.insertRenderObjectChild(renderObject, object);
  renderObjectToWidgetElement.moveRenderObjectChild(renderObject, object);
  renderObjectToWidgetElement.removeRenderObjectChild(renderObject);

  // Changes made in https://docs.flutter.dev/release/breaking-changes/clip-behavior
  ListWheelScrollView listWheelScrollView = ListWheelScrollView();
  listWheelScrollView = ListWheelScrollView(clipBehavior: Clip.hardEdge);
  listWheelScrollView = ListWheelScrollView(clipBehavior: Clip.none);
  listWheelScrollView = ListWheelScrollView(error: '');
  listWheelScrollView = ListWheelScrollView.useDelegate();
  listWheelScrollView = ListWheelScrollView.useDelegate(clipBehavior: Clip.hardEdge);
  listWheelScrollView = ListWheelScrollView.useDelegate(clipBehavior: Clip.none);
  listWheelScrollView = ListWheelScrollView.useDelegate(error: '');
  listWheelScrollView.clipBehavior;
  ListWheelViewport listWheelViewport = ListWheelViewport();
  listWheelViewport = ListWheelViewport(clipBehavior: Clip.hardEdge);
  listWheelViewport = ListWheelViewport(clipBehavior: Clip.none);
  listWheelViewport = ListWheelViewport(error: '');
  listWheelViewport.clipBehavior;

  // Changes made in https://github.com/flutter/flutter/pull/87839
  OverscrollIndicatorNotification notification =
      OverscrollIndicatorNotification(leading: true);
  notification = OverscrollIndicatorNotification(error: '');
  notification.disallowIndicator();

  // Changes made in https://github.com/flutter/flutter/pull/96957
  CupertinoScrollbar scrollbar = CupertinoScrollbar(thumbVisibility: true);
  bool nowShowing = scrollbar.thumbVisibility;
  RawScrollbar rawScrollbar = RawScrollbar(thumbVisibility: true);
  nowShowing = rawScrollbar.thumbVisibility;

  // Change made in https://github.com/flutter/flutter/pull/100381
  SelectionOverlay.fadeDuration;

  // Changes made in https://github.com/flutter/flutter/pull/78588
  final ScrollBehavior scrollBehavior = ScrollBehavior();
  scrollBehavior.buildOverscrollIndicator(context, child, axisDirection);
  final CupertinoScrollBehavior cupertinoScrollBehavior =
      CupertinoScrollBehavior();
  cupertinoScrollBehavior.buildOverscrollIndicator(context, child, axisDirection);

  // Changes made in https://github.com/flutter/flutter/pull/114459
  MediaQuery.boldTextOf(context);

  // Changes made in https://github.com/flutter/flutter/pull/122555
  final ScrollableDetails details = ScrollableDetails(
    direction: AxisDirection.down,
    decorationClipBehavior: Clip.none,
  );
  final Clip clip = details.decorationClipBehavior;

  final PlatformMenuBar platformMenuBar = PlatformMenuBar(
    menus: <PlatformMenuItem>[],
    child: const SizedBox(),
  );
  final Widget bodyValue = platformMenuBar.child;

  // Changes made in https://github.com/flutter/flutter/pull/151367
  final cupertinoSwitch = CupertinoSwitch(
    value: value,
    onChanged: onChanged,
    activeTrackColor: Colors.red,
  );
  Color? activeTrackColor = cupertinoSwitch.activeTrackColor;

  // Changes made in https://github.com/flutter/flutter/pull/151367
  final cupertinoSwitch = CupertinoSwitch(
    value: value,
    onChanged: onChanged,
    inactiveTrackColor: Colors.red,
  );
  Color? inactiveTrackColor = cupertinoSwitch.inactiveTrackColor;

  // https://github.com/flutter/flutter/pull/152981
  CupertinoCheckbox(fillColor: WidgetStateProperty.resolveWith<Color>((Set<WidgetState> states) {
 if (states.contains(WidgetState.disabled)) {
 return CupertinoColors.white.withValues(alpha: 0.5);
 }
 if (states.contains(WidgetState.selected)) {
 return CupertinoDynamicColor.resolve(CupertinoDynamicColor.withBrightness(
 color: CupertinoColors.activeBlue,
 darkColor: Color.fromARGB(255, 50, 100, 215),
 ), context);
 }
 return Colors.red;
 }));
  CupertinoCheckbox(activeColor: Colors.white, fillColor: WidgetStateProperty.resolveWith<Color>((Set<WidgetState> states) {
 if (states.contains(WidgetState.disabled)) {
 return CupertinoColors.white.withValues(alpha: 0.5);
 }
 if (states.contains(WidgetState.selected)) {
 return Colors.white;
 }
 return Colors.red;
 }));
  CupertinoCheckbox(
    fillColor: WidgetStatePropertyAll(CupertinoColors.white),
  );

  // https://github.com/flutter/flutter/pull/161295
  CupertinoButton(minimumSize: Size(60.0, 60.0));

  // https://github.com/flutter/flutter/pull/170625
  showCupertinoSheet(
    context: context,
    scrollableBuilder: (BuildContext context, ScrollController controller) {
      WidgetBuilder widgetBuilder = (BuildContext context) => Container();
      return widgetBuilder(context);
    },
  );

  // https://github.com/flutter/flutter/pull/171160
  CupertinoDynamicColor dynamicColor = CupertinoDynamicColor.withBrightness(
    color: Color(0xFF000000),
    darkColor: Color(0xFF000001),
  );
  dynamicColor.a;
  dynamicColor.toARGB32();
  dynamicColor = dynamicColor.withValues(alpha: 0.55);

  // Changes made in https://github.com/flutter/flutter/pull/177337
  showCupertinoSheet(
    context: context,
    scrollableBuilder: (BuildContext context, ScrollController controller) {
      WidgetBuilder widgetBuilder = (BuildContext context) => Container();
      return widgetBuilder(context);
    },
  );

  // Changes made in https://github.com/flutter/flutter/pull/177337
  CupertinoSheetRoute<void>(
    context: context,
    scrollableBuilder: (BuildContext context, ScrollController controller) {
      WidgetBuilder widgetBuilder = (BuildContext context) => Container();
      return widgetBuilder(context);
    },
  );
}
