@Override
  protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doGetRestorableState(rs, context);

    rs.addStateValueAsDouble(context, "leftAzimuthDegrees", this.leftAzimuth.degrees);
    rs.addStateValueAsDouble(context, "rightAzimuthDegrees", this.rightAzimuth.degrees);
  }
  @Override
  protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doGetRestorableState(rs, context);

    rs.addStateValueAsBoolean(context, "enableCaps", this.enableCaps);

    if (this.locations != null) rs.addStateValueAsLatLonList(context, "locations", this.locations);
  }
  @Override
  protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doRestoreState(rs, context);

    Boolean booleanState = rs.getStateValueAsBoolean(context, "enableCaps");
    if (booleanState != null) this.setEnableCaps(booleanState);

    List<LatLon> locations = rs.getStateValueAsLatLonList(context, "locations");
    if (locations != null) this.setLocations(locations);
  }
  protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doGetRestorableState(rs, context);

    if (this.boundaries.getContourCount() > 0) {
      RestorableSupport.StateObject so = rs.addStateObject(context, "boundaries");
      for (int i = 0; i < this.boundaries.getContourCount(); i++) {
        rs.addStateValueAsLatLonList(so, "boundary", this.boundaries.getContour(i));
      }
    }
  }
  @Override
  protected void doGetRestorableState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doGetRestorableState(rs, context);

    RestorableSupport.StateObject so = rs.addStateObject(context, "layers");
    for (Layer layer : this.layers) {
      RestorableSupport.StateObject lso = rs.addStateObject(so, "layer");
      layer.doGetRestorableState(rs, lso);
    }
  }
  @Override
  protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doRestoreState(rs, context);

    Double la = rs.getStateValueAsDouble(context, "leftAzimuthDegrees");
    if (la == null) la = this.leftAzimuth.degrees;

    Double ra = rs.getStateValueAsDouble(context, "rightAzimuthDegrees");
    if (ra == null) ra = this.rightAzimuth.degrees;

    this.setAzimuths(Angle.fromDegrees(la), Angle.fromDegrees(ra));
  }
  protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doRestoreState(rs, context);

    RestorableSupport.StateObject so = rs.getStateObject(context, "boundaries");
    if (so != null) {
      this.boundaries.removeAllContours();

      RestorableSupport.StateObject[] sos = rs.getAllStateObjects(so, "boundary");
      if (sos != null) {
        for (RestorableSupport.StateObject boundary : sos) {
          if (boundary == null) continue;

          Iterable<LatLon> locations = rs.getStateObjectAsLatLonList(boundary);
          if (locations != null) this.boundaries.addContour(locations);
        }
      }

      // We've changed the polygon's list of boundaries; flag the shape as changed.
      this.onShapeChanged();
    }
  }
  @Override
  protected void doRestoreState(RestorableSupport rs, RestorableSupport.StateObject context) {
    super.doRestoreState(rs, context);

    RestorableSupport.StateObject so = rs.getStateObject(context, "layers");
    if (so == null) return;

    RestorableSupport.StateObject[] lsos = rs.getAllStateObjects(so, "layer");
    if (lsos == null || lsos.length == 0) return;

    ArrayList<Layer> layerList = new ArrayList<Layer>(lsos.length);

    for (RestorableSupport.StateObject lso : lsos) {
      if (lso != null) {
        Layer layer = new Layer();
        layer.doRestoreState(rs, lso);
        layerList.add(layer);
      }
    }

    this.setLayers(layerList);
  }
  public void getRestorableStateForAVPair(
      String key, Object value, RestorableSupport rs, RestorableSupport.StateObject context) {
    if (value == null) return;

    if (key.equals(PROPERTY_CHANGE_SUPPORT)) return;

    if (rs == null) {
      String message = Logging.getMessage("nullValue.RestorableStateIsNull");
      Logging.logger().severe(message);
      throw new IllegalArgumentException(message);
    }

    rs.addStateValueAsString(context, key, value.toString());
  }