gt:         if (!categoryAxis.getCategories().contains(category)) {
context: /*
   * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  package javafx.scene.chart;
  
  import java.util.*;
  
  import javafx.scene.AccessibleRole;
  import javafx.animation.Animation;
  import javafx.animation.FadeTransition;
  import javafx.animation.Interpolator;
  import javafx.animation.KeyFrame;
  import javafx.animation.KeyValue;
  import javafx.animation.ParallelTransition;
  import javafx.animation.Timeline;
  import javafx.application.Platform;
  import javafx.beans.NamedArg;
  import javafx.beans.property.DoubleProperty;
  import javafx.beans.value.WritableValue;
  import javafx.collections.FXCollections;
  import javafx.collections.ObservableList;
  import javafx.geometry.Orientation;
  import javafx.scene.Node;
  import javafx.scene.layout.StackPane;
  import javafx.util.Duration;
  
  import com.sun.javafx.charts.Legend;
  import com.sun.javafx.charts.Legend.LegendItem;
  
  import javafx.css.StyleableDoubleProperty;
  import javafx.css.CssMetaData;
  import javafx.css.PseudoClass;
  
  import com.sun.javafx.css.converters.SizeConverter;
  
  import javafx.css.Styleable;
  import javafx.css.StyleableProperty;
  
  /**
   * A chart that plots bars indicating data values for a category. The bars can be vertical or horizontal depending on
   * which axis is a category axis.
   * @since JavaFX 2.0
   */
  public class BarChart<X,Y> extends XYChart<X,Y> {
  
      // -------------- PRIVATE FIELDS -------------------------------------------
      
      private Map<Series<X,Y>, Map<String, Data<X,Y>>> seriesCategoryMap = new HashMap<>();
      private Legend legend = new Legend();
      private final Orientation orientation;
      private CategoryAxis categoryAxis;
      private ValueAxis valueAxis;
      private Timeline dataRemoveTimeline;
      private double bottomPos  = 0;
      private static String NEGATIVE_STYLE = "negative";
      private ParallelTransition pt;
      // For storing data values in case removed and added immediately.
      private Map<Data<X,Y>, Double> XYValueMap = 
                                  new HashMap<Data<X,Y>, Double>();
      // -------------- PUBLIC PROPERTIES ----------------------------------------
  
      /** The gap to leave between bars in the same category */
      private DoubleProperty barGap = new StyleableDoubleProperty(4) {
          @Override protected void invalidated() {
              get();
              requestChartLayout();
          }
          
          public Object getBean() {
              return BarChart.this;
          }
  
          public String getName() {
              return "barGap";
          }
  
          public CssMetaData<BarChart<?,?>,Number> getCssMetaData() {
              return StyleableProperties.BAR_GAP;
          }
      };
      public final double getBarGap() { return barGap.getValue(); }
      public final void setBarGap(double value) { barGap.setValue(value); }
      public final DoubleProperty barGapProperty() { return barGap; }
  
      /** The gap to leave between bars in separate categories */
      private DoubleProperty categoryGap = new StyleableDoubleProperty(10) {
          @Override protected void invalidated() {
              get();
              requestChartLayout();
          }
  
          @Override
          public Object getBean() {
              return BarChart.this;
          }
  
          @Override
          public String getName() {
              return "categoryGap";
          }
  
          public CssMetaData<BarChart<?,?>,Number> getCssMetaData() {
              return StyleableProperties.CATEGORY_GAP;
          }
      };
      public final double getCategoryGap() { return categoryGap.getValue(); }
      public final void setCategoryGap(double value) { categoryGap.setValue(value); }
      public final DoubleProperty categoryGapProperty() { return categoryGap; }
  
      // -------------- CONSTRUCTOR ----------------------------------------------
  
      /**
       * Construct a new BarChart with the given axis. The two axis should be a ValueAxis/NumberAxis and a CategoryAxis,
       * they can be in either order depending on if you want a horizontal or vertical bar chart.
       *
       * @param xAxis The x axis to use
       * @param yAxis The y axis to use
       */
      public BarChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis) {
          this(xAxis, yAxis, FXCollections.<Series<X, Y>>observableArrayList());
      }
  
      /**
       * Construct a new BarChart with the given axis and data. The two axis should be a ValueAxis/NumberAxis and a
       * CategoryAxis, they can be in either order depending on if you want a horizontal or vertical bar chart.
       *
       * @param xAxis The x axis to use
       * @param yAxis The y axis to use
       * @param data The data to use, this is the actual list used so any changes to it will be reflected in the chart
       */
      public BarChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data) {
          super(xAxis, yAxis);
          getStyleClass().add("bar-chart");
          setLegend(legend);
          if (!((xAxis instanceof ValueAxis && yAxis instanceof CategoryAxis) ||
               (yAxis instanceof ValueAxis && xAxis instanceof CategoryAxis))) {
              throw new IllegalArgumentException("Axis type incorrect, one of X,Y should be CategoryAxis and the other NumberAxis");
          }
          if (xAxis instanceof CategoryAxis) {
              categoryAxis = (CategoryAxis)xAxis;
              valueAxis = (ValueAxis)yAxis;
              orientation = Orientation.VERTICAL;
          } else {
              categoryAxis = (CategoryAxis)yAxis;
              valueAxis = (ValueAxis)xAxis;
              orientation = Orientation.HORIZONTAL;
          }
          // update css
          pseudoClassStateChanged(HORIZONTAL_PSEUDOCLASS_STATE, orientation == Orientation.HORIZONTAL);
          pseudoClassStateChanged(VERTICAL_PSEUDOCLASS_STATE, orientation == Orientation.VERTICAL);
          setData(data);
      }
  
      /**
       * Construct a new BarChart with the given axis and data. The two axis should be a ValueAxis/NumberAxis and a
       * CategoryAxis, they can be in either order depending on if you want a horizontal or vertical bar chart.
       *
       * @param xAxis The x axis to use
       * @param yAxis The y axis to use
       * @param data The data to use, this is the actual list used so any changes to it will be reflected in the chart
       * @param categoryGap The gap to leave between bars in separate categories
       */
       public BarChart(@NamedArg("xAxis") Axis<X> xAxis, @NamedArg("yAxis") Axis<Y> yAxis, @NamedArg("data") ObservableList<Series<X,Y>> data, @NamedArg("categoryGap") double categoryGap) {
          this(xAxis, yAxis);
          setData(data);
          setCategoryGap(categoryGap);
      }
       
      // -------------- PROTECTED METHODS ----------------------------------------
       
      @Override protected void dataItemAdded(Series<X,Y> series, int itemIndex, Data<X,Y> item) {
          String category;
          if (orientation == Orientation.VERTICAL) {
              category = (String)item.getXValue();
          } else {
              category = (String)item.getYValue();
          }
           Map<String, Data<X,Y>> categoryMap = seriesCategoryMap.get(series);
  
          if (categoryMap == null) {
              categoryMap = new HashMap<String, Data<X,Y>>();
              seriesCategoryMap.put(series, categoryMap);
          }
          // check if category is already present
  