All Downloads are FREE. Search and download functionalities are using the official Maven repository.

swim.runtime.lane.ListLaneView Maven / Gradle / Ivy

There is a newer version: 3.10.0
Show newest version
// Copyright 2015-2019 SWIM.AI inc.
//
// 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 swim.runtime.lane;

import java.util.AbstractMap;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import swim.api.Link;
import swim.api.SwimContext;
import swim.api.agent.AgentContext;
import swim.api.data.ListData;
import swim.api.http.function.DecodeRequestHttp;
import swim.api.http.function.DidRequestHttp;
import swim.api.http.function.DidRespondHttp;
import swim.api.http.function.DoRespondHttp;
import swim.api.http.function.WillRequestHttp;
import swim.api.http.function.WillRespondHttp;
import swim.api.lane.Lane;
import swim.api.lane.ListLane;
import swim.api.lane.function.DidCommand;
import swim.api.lane.function.DidEnter;
import swim.api.lane.function.DidLeave;
import swim.api.lane.function.DidUplink;
import swim.api.lane.function.WillCommand;
import swim.api.lane.function.WillEnter;
import swim.api.lane.function.WillLeave;
import swim.api.lane.function.WillUplink;
import swim.concurrent.Conts;
import swim.observable.function.DidClear;
import swim.observable.function.DidDrop;
import swim.observable.function.DidMoveIndex;
import swim.observable.function.DidRemoveIndex;
import swim.observable.function.DidTake;
import swim.observable.function.DidUpdateIndex;
import swim.observable.function.WillClear;
import swim.observable.function.WillDrop;
import swim.observable.function.WillMoveIndex;
import swim.observable.function.WillRemoveIndex;
import swim.observable.function.WillTake;
import swim.observable.function.WillUpdateIndex;
import swim.structure.Form;
import swim.util.KeyedList;

public class ListLaneView extends LaneView implements ListLane {
  protected final AgentContext agentContext;
  protected Form valueForm;

  protected int flags;
  protected ListLaneModel laneBinding;
  protected ListData dataView;

  ListLaneView(AgentContext agentContext, Form valueForm, int flags, Object observers) {
    super(observers);
    this.agentContext = agentContext;
    this.valueForm = valueForm;
    this.flags = flags;
  }

  public ListLaneView(AgentContext agentContext, Form valueForm) {
    this(agentContext, valueForm, 0, null);
  }

  @Override
  public AgentContext agentContext() {
    return this.agentContext;
  }

  @Override
  public ListLaneModel getLaneBinding() {
    return this.laneBinding;
  }

  void setLaneBinding(ListLaneModel laneBinding) {
    this.laneBinding = laneBinding;
    this.dataView = laneBinding.data.valueForm(this.valueForm);
  }

  @Override
  public ListLaneModel createLaneBinding() {
    return new ListLaneModel(this.flags);
  }

  @Override
  public final Form valueForm() {
    return this.valueForm;
  }

  @Override
  public  ListLaneView valueForm(Form valueForm) {
    return new ListLaneView(this.agentContext, valueForm, this.flags,
                                typesafeObservers(this.observers));
  }

  @Override
  public  ListLaneView valueClass(Class valueClass) {
    return valueForm(Form.forClass(valueClass));
  }

  public void setValueForm(Form valueForm) {
    this.valueForm = valueForm;
  }

  protected Object typesafeObservers(Object observers) {
    // TODO: filter out WillUpdateIndex, DidUpdateIndex,
    //       WillMoveIndex, DidMoveIndex, WillRemoveIndex, DidRemoveIndex,
    //       WillDrop, DidDrop, WillTake, DidTake, WillClear, DidClear
    return observers;
  }

  public final boolean isResident() {
    return (this.flags & RESIDENT) != 0;
  }

  @Override
  public ListLaneView isResident(boolean isResident) {
    if (isResident) {
      this.flags |= RESIDENT;
    } else {
      this.flags &= ~RESIDENT;
    }
    final ListLaneModel laneBinding = this.laneBinding;
    if (laneBinding != null) {
      laneBinding.isResident(isResident);
    }
    return this;
  }

  void didSetResident(boolean isResident) {
    if (isResident) {
      this.flags |= RESIDENT;
    } else {
      this.flags &= ~RESIDENT;
    }
  }

  public final boolean isTransient() {
    return (this.flags & TRANSIENT) != 0;
  }

  @Override
  public ListLaneView isTransient(boolean isTransient) {
    if (isTransient) {
      this.flags |= TRANSIENT;
    } else {
      this.flags &= ~TRANSIENT;
    }
    final ListLaneModel laneBinding = this.laneBinding;
    if (laneBinding != null) {
      laneBinding.isTransient(isTransient);
    }
    return this;
  }

  void didSetTransient(boolean isTransient) {
    if (isTransient) {
      this.flags |= TRANSIENT;
    } else {
      this.flags &= ~TRANSIENT;
    }
  }

  @Override
  public final boolean isSigned() {
    return (this.flags & SIGNED) != 0;
  }

  @Override
  public ListLaneView isSigned(boolean isSigned) {
    didSetSigned(isSigned);

    // note: marked final given access of concurrently accessed volatile objects
    final ListLaneModel laneBinding = this.laneBinding;

    if (laneBinding != null) {
      laneBinding.isSigned(isSigned);
    }

    return this;
  }

  void didSetSigned(boolean isSigned) {
    if (isSigned) {
      this.flags |= SIGNED;
    } else {
      this.flags &= ~SIGNED;
    }
  }

  @Override
  public void close() {
    this.laneBinding.closeLaneView(this);
  }

  @SuppressWarnings("unchecked")
  @Override
  public ListLaneView observe(Object observer) {
    return (ListLaneView) super.observe(observer);
  }

  @SuppressWarnings("unchecked")
  @Override
  public ListLaneView unobserve(Object observer) {
    return (ListLaneView) super.unobserve(observer);
  }

  @Override
  public ListLaneView willUpdate(WillUpdateIndex willUpdate) {
    return observe(willUpdate);
  }

  @Override
  public ListLaneView didUpdate(DidUpdateIndex didUpdate) {
    return observe(didUpdate);
  }

  @Override
  public ListLaneView willMove(WillMoveIndex willMove) {
    return observe(willMove);
  }

  @Override
  public ListLaneView didMove(DidMoveIndex didMove) {
    return observe(didMove);
  }

  @Override
  public ListLaneView willRemove(WillRemoveIndex willRemove) {
    return observe(willRemove);
  }

  @Override
  public ListLaneView didRemove(DidRemoveIndex didRemove) {
    return observe(didRemove);
  }

  @Override
  public ListLaneView willDrop(WillDrop willDrop) {
    return observe(willDrop);
  }

  @Override
  public ListLaneView didDrop(DidDrop didDrop) {
    return observe(didDrop);
  }

  @Override
  public ListLaneView willTake(WillTake willTake) {
    return observe(willTake);
  }

  @Override
  public ListLaneView didTake(DidTake didTake) {
    return observe(didTake);
  }

  @Override
  public ListLaneView willClear(WillClear willClear) {
    return observe(willClear);
  }

  @Override
  public ListLaneView didClear(DidClear didClear) {
    return observe(didClear);
  }

  @Override
  public ListLaneView willCommand(WillCommand willCommand) {
    return observe(willCommand);
  }

  @Override
  public ListLaneView didCommand(DidCommand didCommand) {
    return observe(didCommand);
  }

  @Override
  public ListLaneView willUplink(WillUplink willUplink) {
    return observe(willUplink);
  }

  @Override
  public ListLaneView didUplink(DidUplink didUplink) {
    return observe(didUplink);
  }

  @Override
  public ListLaneView willEnter(WillEnter willEnter) {
    return observe(willEnter);
  }

  @Override
  public ListLaneView didEnter(DidEnter didEnter) {
    return observe(didEnter);
  }

  @Override
  public ListLaneView willLeave(WillLeave willLeave) {
    return observe(willLeave);
  }

  @Override
  public ListLaneView didLeave(DidLeave didLeave) {
    return observe(didLeave);
  }

  @Override
  public ListLaneView decodeRequest(DecodeRequestHttp decodeRequest) {
    return observe(decodeRequest);
  }

  @Override
  public ListLaneView willRequest(WillRequestHttp willRequest) {
    return observe(willRequest);
  }

  @Override
  public ListLaneView didRequest(DidRequestHttp didRequest) {
    return observe(didRequest);
  }

  @Override
  public ListLaneView doRespond(DoRespondHttp doRespond) {
    return observe(doRespond);
  }

  @Override
  public ListLaneView willRespond(WillRespondHttp willRespond) {
    return observe(willRespond);
  }

  @Override
  public ListLaneView didRespond(DidRespondHttp didRespond) {
    return observe(didRespond);
  }

  @SuppressWarnings("unchecked")
  protected Map.Entry dispatchWillUpdate(Link link, int index, V newValue, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof WillUpdateIndex) {
        if (((WillUpdateIndex) observers).isPreemptive() == preemptive) {
          try {
            newValue = ((WillUpdateIndex) observers).willUpdate(index, newValue);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof WillUpdateIndex) {
            if (((WillUpdateIndex) observer).isPreemptive() == preemptive) {
              try {
                newValue = ((WillUpdateIndex) observer).willUpdate(index, newValue);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return new AbstractMap.SimpleImmutableEntry(complete, newValue);
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  @SuppressWarnings("unchecked")
  protected boolean dispatchDidUpdate(Link link, int index, V newValue, V oldValue, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof DidUpdateIndex) {
        if (((DidUpdateIndex) observers).isPreemptive() == preemptive) {
          try {
            ((DidUpdateIndex) observers).didUpdate(index, newValue, oldValue);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof DidUpdateIndex) {
            if (((DidUpdateIndex) observer).isPreemptive() == preemptive) {
              try {
                ((DidUpdateIndex) observer).didUpdate(index, newValue, oldValue);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  @SuppressWarnings("unchecked")
  protected boolean dispatchWillMove(Link link, int fromIndex, int toIndex, V value, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof WillMoveIndex) {
        if (((WillMoveIndex) observers).isPreemptive() == preemptive) {
          try {
            ((WillMoveIndex) observers).willMove(fromIndex, toIndex, value);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof WillMoveIndex) {
            if (((WillMoveIndex) observer).isPreemptive() == preemptive) {
              try {
                ((WillMoveIndex) observer).willMove(fromIndex, toIndex, value);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  @SuppressWarnings("unchecked")
  protected boolean dispatchDidMove(Link link, int fromIndex, int toIndex, V value, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof DidMoveIndex) {
        if (((DidMoveIndex) observers).isPreemptive() == preemptive) {
          try {
            ((DidMoveIndex) observers).didMove(fromIndex, toIndex, value);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof DidMoveIndex) {
            if (((DidMoveIndex) observer).isPreemptive() == preemptive) {
              try {
                ((DidMoveIndex) observer).didMove(fromIndex, toIndex, value);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchWillRemove(Link link, int index, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof WillRemoveIndex) {
        if (((WillRemoveIndex) observers).isPreemptive() == preemptive) {
          try {
            ((WillRemoveIndex) observers).willRemove(index);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof WillRemoveIndex) {
            if (((WillRemoveIndex) observer).isPreemptive() == preemptive) {
              try {
                ((WillRemoveIndex) observer).willRemove(index);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  @SuppressWarnings("unchecked")
  protected boolean dispatchDidRemove(Link link, int index, V oldValue, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof DidRemoveIndex) {
        if (((DidRemoveIndex) observers).isPreemptive() == preemptive) {
          try {
            ((DidRemoveIndex) observers).didRemove(index, oldValue);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof DidRemoveIndex) {
            if (((DidRemoveIndex) observer).isPreemptive() == preemptive) {
              try {
                ((DidRemoveIndex) observer).didRemove(index, oldValue);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchWillDrop(Link link, int lower, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof WillDrop) {
        if (((WillDrop) observers).isPreemptive() == preemptive) {
          try {
            ((WillDrop) observers).willDrop(lower);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof WillDrop) {
            if (((WillDrop) observer).isPreemptive() == preemptive) {
              try {
                ((WillDrop) observer).willDrop(lower);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchDidDrop(Link link, int lower, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof DidDrop) {
        if (((DidDrop) observers).isPreemptive() == preemptive) {
          try {
            ((DidDrop) observers).didDrop(lower);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof DidDrop) {
            if (((DidDrop) observer).isPreemptive() == preemptive) {
              try {
                ((DidDrop) observer).didDrop(lower);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchWillTake(Link link, int upper, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof WillTake) {
        if (((WillTake) observers).isPreemptive() == preemptive) {
          try {
            ((WillTake) observers).willTake(upper);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof WillTake) {
            if (((WillTake) observer).isPreemptive() == preemptive) {
              try {
                ((WillTake) observer).willTake(upper);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchDidTake(Link link, int upper, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof DidTake) {
        if (((DidTake) observers).isPreemptive() == preemptive) {
          try {
            ((DidTake) observers).didTake(upper);
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof DidTake) {
            if (((DidTake) observer).isPreemptive() == preemptive) {
              try {
                ((DidTake) observer).didTake(upper);
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchWillClear(Link link, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof WillClear) {
        if (((WillClear) observers).isPreemptive() == preemptive) {
          try {
            ((WillClear) observers).willClear();
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof WillClear) {
            if (((WillClear) observer).isPreemptive() == preemptive) {
              try {
                ((WillClear) observer).willClear();
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  protected boolean dispatchDidClear(Link link, boolean preemptive) {
    final Lane oldLane = SwimContext.getLane();
    final Link oldLink = SwimContext.getLink();
    try {
      SwimContext.setLane(this);
      SwimContext.setLink(link);
      final Object observers = this.observers;
      boolean complete = true;
      if (observers instanceof DidClear) {
        if (((DidClear) observers).isPreemptive() == preemptive) {
          try {
            ((DidClear) observers).didClear();
          } catch (Throwable error) {
            if (Conts.isNonFatal(error)) {
              laneDidFail(error);
            } else {
              throw error;
            }
          }
        } else if (preemptive) {
          complete = false;
        }
      } else if (observers instanceof Object[]) {
        final Object[] array = (Object[]) observers;
        for (int i = 0, n = array.length; i < n; i += 1) {
          final Object observer = array[i];
          if (observer instanceof DidClear) {
            if (((DidClear) observer).isPreemptive() == preemptive) {
              try {
                ((DidClear) observer).didClear();
              } catch (Throwable error) {
                if (Conts.isNonFatal(error)) {
                  laneDidFail(error);
                } else {
                  throw error;
                }
              }
            } else if (preemptive) {
              complete = false;
            }
          }
        }
      }
      return complete;
    } finally {
      SwimContext.setLink(oldLink);
      SwimContext.setLane(oldLane);
    }
  }

  public V laneWillInsert(int index, V newValue) {
    return newValue;
  }

  public void laneDidInsert(int index, V newValue) {
  }

  public V laneWillUpdate(int index, V newValue) {
    return newValue;
  }

  public void laneDidUpdate(int index, V newValue, V oldValue) {
  }

  public void laneWillMove(int fromIndex, int toIndex, V value) {

  }

  public void laneDidMove(int fromIndex, int toIndex, V value) {
  }

  public void laneWillRemove(int index) {
  }

  public void laneDidRemove(int index, V oldValue) {
  }

  public void laneWillDrop(int lower) {
  }

  public void laneDidDrop(int lower) {
  }

  public void laneWillTake(int upper) {
  }

  public void laneDidTake(int upper) {
  }

  public void laneWillClear() {
  }

  public void laneDidClear() {
  }

  @Override
  public boolean isEmpty() {
    return this.dataView.isEmpty();
  }

  @Override
  public boolean contains(Object o) {
    return this.dataView.contains(o);
  }

  @Override
  public Iterator iterator() {
    return this.dataView.iterator();
  }

  @Override
  public Object[] toArray() {
    return this.dataView.toArray();
  }

  @Override
  public  T[] toArray(T[] a) {
    return this.dataView.toArray(a);
  }

  @Override
  public boolean add(V v) {
    return this.laneBinding.add(this, size(), v);
  }

  @Override
  public boolean remove(Object o) {
    final int index = indexOf(o);
    if (index != -1) {
      final V oldObject = this.laneBinding.remove(this, index);
      return oldObject != null && oldObject != this.valueForm.unit(); // TODO
    }
    return false;
  }

  @Override
  public boolean containsAll(Collection elements) {
    return this.dataView.containsAll(elements);
  }

  @Override
  public boolean addAll(Collection elements) {
    boolean added = false;
    for (V element: elements) {
      added = added || add(element);
    }
    return added;
  }

  @Override
  public boolean addAll(int index, Collection elements) {
    int position = index;
    for (V element: elements) {
      add(position++, element);
    }
    return elements.isEmpty();
  }

  @Override
  public boolean removeAll(Collection elements) {
    boolean didRemove = false;
    for (Object element: elements) {
      final int index = indexOf(element);
      if (index != -1) {
        didRemove = didRemove || remove(element);
      }
    }
    return didRemove;
  }

  @Override
  public boolean retainAll(Collection elements) {
    boolean modified = false;
    for (Object element: elements) {
      if (!elements.contains(element)) {
        modified = modified || remove(element);
      }
    }
    return modified;
  }

  @Override
  public int size() {
    return this.dataView.size();
  }

  @Override
  public void drop(int lower) {
    this.laneBinding.drop(this, lower);
  }

  @Override
  public void take(int upper) {
    this.laneBinding.take(this, upper);
  }

  @Override
  public void clear() {
    this.laneBinding.clear(this);
  }

  @Override
  public V get(int index) {
    return this.dataView.get(index);
  }

  @Override
  public V set(int index, V element) {
    return this.laneBinding.set(this, index, element);
  }

  @Override
  public void add(int index, V element) {
    this.laneBinding.add(this, index, element);
  }

  @Override
  public V remove(int index) {
    return this.laneBinding.remove(this, index);
  }

  @Override
  public int indexOf(Object o) {
    return this.dataView.indexOf(o);
  }

  @Override
  public int lastIndexOf(Object o) {
    return this.dataView.lastIndexOf(o);
  }

  @Override
  public ListIterator listIterator() {
    return this.dataView.listIterator();
  }

  @Override
  public ListIterator listIterator(int index) {
    return this.dataView.listIterator(index);
  }

  @Override
  public List subList(int fromIndex, int toIndex) {
    return this.dataView.subList(fromIndex, toIndex);
  }

  @Override
  public KeyedList snapshot() {
    return this.dataView.snapshot();
  }

  @Override
  public V get(int index, Object key) {
    return this.dataView.get(index, key);
  }

  @Override
  public Map.Entry getEntry(int index) {
    return this.dataView.getEntry(index);
  }

  @Override
  public Map.Entry getEntry(int index, Object key) {
    return this.dataView.getEntry(index, key);
  }

  @Override
  public V set(int index, V element, Object key) {
    return this.laneBinding.set(this, index, element, key);
  }

  @Override
  public boolean add(V element, Object key) {
    return this.laneBinding.add(this, size(), element, key);
  }

  @Override
  public void add(int index, V element, Object key) {
    this.laneBinding.add(this, index, element, key);
  }

  @Override
  public V remove(int index, Object key) {
    return this.laneBinding.remove(this, index, key);
  }

  @Override
  public void move(int fromIndex, int toIndex) {
    this.laneBinding.move(fromIndex, toIndex);
  }

  @Override
  public void move(int fromIndex, int toIndex, Object key) {
    this.laneBinding.move(fromIndex, toIndex, key);
  }

  @Override
  public ListIterator keyIterator() {
    return this.dataView.keyIterator();
  }

  @Override
  public ListIterator> entryIterator() {
    return this.dataView.entryIterator();
  }

  static final int RESIDENT = 1 << 0;
  static final int TRANSIENT = 1 << 1;
  static final int SIGNED = 1 << 2;
}