gt:             StringPropertyBase ref = wref.get();
context: /*
   * Copyright (c) 2011, 2014, 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.beans.property;
  
  import javafx.beans.InvalidationListener;
  import javafx.beans.Observable;
  import javafx.beans.value.ChangeListener;
  import javafx.beans.value.ObservableValue;
  
  import com.sun.javafx.binding.ExpressionHelper;
  import java.lang.ref.WeakReference;
  
  /**
   * The class {@code StringPropertyBase} is the base class for a property
   * wrapping a {@code String} value.
   *
   * It provides all the functionality required for a property except for the
   * {@link #getBean()} and {@link #getName()} methods, which must be implemented
   * by extending classes.
   *
   * @see StringProperty
   *
   *
   * @since JavaFX 2.0
   */
  public abstract class StringPropertyBase extends StringProperty {
  
      private String value;
      private ObservableValue<? extends String> observable = null;
      private InvalidationListener listener = null;
      private boolean valid = true;
      private ExpressionHelper<String> helper = null;
  
      /**
       * The constructor of the {@code StringPropertyBase}.
       */
      public StringPropertyBase() {
      }
  
      /**
       * The constructor of the {@code StringPropertyBase}.
       *
       * @param initialValue
       *            the initial value of the wrapped {@code String}
       */
      public StringPropertyBase(String initialValue) {
          this.value = initialValue;
      }
  
      @Override
      public void addListener(InvalidationListener listener) {
          helper = ExpressionHelper.addListener(helper, this, listener);
      }
  
      @Override
      public void removeListener(InvalidationListener listener) {
          helper = ExpressionHelper.removeListener(helper, listener);
      }
  
      @Override
      public void addListener(ChangeListener<? super String> listener) {
          helper = ExpressionHelper.addListener(helper, this, listener);
      }
  
      @Override
      public void removeListener(ChangeListener<? super String> listener) {
          helper = ExpressionHelper.removeListener(helper, listener);
      }
  
      /**
       * Sends notifications to all attached
       * {@link javafx.beans.InvalidationListener InvalidationListeners} and
       * {@link javafx.beans.value.ChangeListener ChangeListeners}.
       *
       * This method is called when the value is changed, either manually by
       * calling {@link #set} or in case of a bound property, if the
       * binding becomes invalid.
       */
      protected void fireValueChangedEvent() {
          ExpressionHelper.fireValueChangedEvent(helper);
      }
  
      private void markInvalid() {
          if (valid) {
              valid = false;
              invalidated();
              fireValueChangedEvent();
          }
      }
  
      /**
       * The method {@code invalidated()} can be overridden to receive
       * invalidation notifications. This is the preferred option in
       * {@code Objects} defining the property, because it requires less memory.
       *
       * The default implementation is empty.
       */
      protected void invalidated() {
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public String get() {
          valid = true;
          return observable == null ? value : observable.getValue();
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public void set(String newValue) {
          if (isBound()) {
              throw new java.lang.RuntimeException((getBean() != null && getName() != null ?
                      getBean().getClass().getSimpleName() + "." + getName() + " : ": "") + "A bound value cannot be set.");
          }
          if ((value == null)? newValue != null : !value.equals(newValue)) {
              value = newValue;
              markInvalid();
          }
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public boolean isBound() {
          return observable != null;
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public void bind(ObservableValue<? extends String> newObservable) {
          if (newObservable == null) {
              throw new NullPointerException("Cannot bind to null");
          }
          if (!newObservable.equals(observable)) {
              unbind();
              observable = newObservable;
              if (listener == null) {
                  listener = new Listener(this);
              }
              observable.addListener(listener);
              markInvalid();
          }
      }
  
      /**
       * {@inheritDoc}
       */
      @Override
      public void unbind() {
          if (observable != null) {
              value = observable.getValue();
              observable.removeListener(listener);
              observable = null;
          }
      }
  
      /**
       * Returns a string representation of this {@code StringPropertyBase} object.
       * @return a string representation of this {@code StringPropertyBase} object.
       */
      @Override
      public String toString() {
          final Object bean = getBean();
          final String name = getName();
          final StringBuilder result = new StringBuilder("StringProperty [");
          if (bean != null) {
              result.append("bean: ").append(bean).append(", ");
          }
          if ((name != null) && (!name.equals(""))) {
              result.append("name: ").append(name).append(", ");
          }
          if (isBound()) {
              result.append("bound, ");
              if (valid) {
                  result.append("value: ").append(get());
              } else {
                  result.append("invalid");
              }
          } else {
              result.append("value: ").append(get());
          }
          result.append("]");
          return result.toString();
      }
  
      private static class Listener implements InvalidationListener {
  
          private final WeakReference<StringPropertyBase> wref;
  
          public Listener(StringPropertyBase ref) {
              this.wref = new WeakReference<>(ref);
          }
  
          @Override
          public void invalidated(Observable observable) {
  