<commit_before>package com.getbase.android.autoprovider;

import com.google.common.collect.Iterables;

import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.database.ContentObservable;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.net.Uri;
import android.os.Build;

import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.LinkedHashSet;

public class MultiUriCursorWrapper extends CursorWrapper {

  public MultiUriCursorWrapper(Cursor cursor) {
    super(cursor);
  }

  protected boolean mClosed;
  protected ContentResolver mContentResolver;

  private final LinkedHashSet<Uri> mNotifyUris = new LinkedHashSet<>();

  private final Object mSelfObserverLock = new Object();
  private ContentObserver mSelfObserver;
  private boolean mSelfObserverRegistered;

  private final LinkedHashSet<Uri> mChangedByUris = new LinkedHashSet<>();

  private final ContentObservable mContentObservable = new ContentObservable();

  @Override
  public void deactivate() {
    onDeactivateOrClose();
    super.deactivate();
  }

  protected void onDeactivateOrClose() {
    if (mSelfObserver != null) {
      mContentResolver.unregisterContentObserver(mSelfObserver);
      mSelfObserverRegistered = false;
    }
  }

  @Override
  public boolean requery() {
    if (mSelfObserver != null && !mSelfObserverRegistered) {
      for (Uri notifyUri : mNotifyUris) {
        mContentResolver.registerContentObserver(notifyUri, true, mSelfObserver);
      }
      mSelfObserverRegistered = true;
    }

    boolean success = super.requery();
    if (success) {
      mChangedByUris.clear();
    }
    return success;
  }

  @Override
  public boolean isClosed() {
    return super.isClosed() && mClosed;
  }

  @Override
  public void close() {
    super.close();

    mClosed = true;
    mContentObservable.unregisterAll();
    onDeactivateOrClose();
  }

  @SuppressWarnings("deprecation")
  @Override
  public void registerContentObserver(ContentObserver observer) {
    mContentObservable.registerObserver(observer);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      dispatchChangeForUris(observer);
    } else {
      if (!mChangedByUris.isEmpty()) {
        observer.dispatchChange(false);
      }
    }
  }

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  private void dispatchChangeForUris(ContentObserver observer) {
    for (Uri changedByUri : mChangedByUris) {
      observer.dispatchChange(false, changedByUri);
    }
  }

  @Override
  public void unregisterContentObserver(ContentObserver observer) {
    // cursor will unregister all observers when it close
    if (!mClosed) {
      mContentObservable.unregisterObserver(observer);
    }
  }

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  @SuppressWarnings("deprecation")
  private void onChange(boolean selfChange, Uri uri) {
    synchronized (mSelfObserverLock) {

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        mContentObservable.dispatchChange(selfChange, uri);
      } else {
        mContentObservable.dispatchChange(selfChange);
      }

      if (selfChange) {
        for (Uri notifyUri : mNotifyUris) {
          mContentResolver.notifyChange(notifyUri, mSelfObserver);
        }
      }

      if (!selfChange) {
        mChangedByUris.add(uri);
      }
    }
  }

  public MultiUriCursorWrapper withNotificationUris(ContentResolver cr, Iterable<Uri> uris) {
    synchronized (mSelfObserverLock) {
      Iterables.addAll(mNotifyUris, uris);
      mContentResolver = cr;
      if (mSelfObserver == null) {
        mSelfObserver = new SelfContentObserver(this);
      }

      for (Uri uri : uris) {
        mContentResolver.registerContentObserver(uri, true, mSelfObserver);
      }

      mSelfObserverRegistered = true;
    }

    return this;
  }

  public MultiUriCursorWrapper withNotificationUri(ContentResolver cr, Uri uri) {
    return withNotificationUris(cr, Collections.singletonList(uri));
  }

  public LinkedHashSet<Uri> getNotificationUris() {
    return mNotifyUris;
  }

  @Override
  public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
    withNotificationUri(cr, notifyUri);
  }

  @Override
  public Uri getNotificationUri() {
    synchronized (mSelfObserverLock) {
      return Iterables.getFirst(mNotifyUris, null);<commit_msg>Fix one cause of ConcurrentModificationExceptions<commit_after>package com.getbase.android.autoprovider;

import com.google.common.collect.Iterables;

import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.database.ContentObservable;
import android.database.ContentObserver;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.net.Uri;
import android.os.Build;

import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class MultiUriCursorWrapper extends CursorWrapper {

  public MultiUriCursorWrapper(Cursor cursor) {
    super(cursor);
  }

  protected boolean mClosed;
  protected ContentResolver mContentResolver;

  private final Set<Uri> mNotifyUris = new CopyOnWriteArraySet<>();

  private final Object mSelfObserverLock = new Object();
  private ContentObserver mSelfObserver;
  private boolean mSelfObserverRegistered;

  private final LinkedHashSet<Uri> mChangedByUris = new LinkedHashSet<>();

  private final ContentObservable mContentObservable = new ContentObservable();

  @Override
  public void deactivate() {
    onDeactivateOrClose();
    super.deactivate();
  }

  protected void onDeactivateOrClose() {
    if (mSelfObserver != null) {
      mContentResolver.unregisterContentObserver(mSelfObserver);
      mSelfObserverRegistered = false;
    }
  }

  @Override
  public boolean requery() {
    if (mSelfObserver != null && !mSelfObserverRegistered) {
      for (Uri notifyUri : mNotifyUris) {
        mContentResolver.registerContentObserver(notifyUri, true, mSelfObserver);
      }
      mSelfObserverRegistered = true;
    }

    boolean success = super.requery();
    if (success) {
      mChangedByUris.clear();
    }
    return success;
  }

  @Override
  public boolean isClosed() {
    return super.isClosed() && mClosed;
  }

  @Override
  public void close() {
    super.close();

    mClosed = true;
    mContentObservable.unregisterAll();
    onDeactivateOrClose();
  }

  @SuppressWarnings("deprecation")
  @Override
  public void registerContentObserver(ContentObserver observer) {
    mContentObservable.registerObserver(observer);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      dispatchChangeForUris(observer);
    } else {
      if (!mChangedByUris.isEmpty()) {
        observer.dispatchChange(false);
      }
    }
  }

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  private void dispatchChangeForUris(ContentObserver observer) {
    for (Uri changedByUri : mChangedByUris) {
      observer.dispatchChange(false, changedByUri);
    }
  }

  @Override
  public void unregisterContentObserver(ContentObserver observer) {
    // cursor will unregister all observers when it close
    if (!mClosed) {
      mContentObservable.unregisterObserver(observer);
    }
  }

  @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
  @SuppressWarnings("deprecation")
  private void onChange(boolean selfChange, Uri uri) {
    synchronized (mSelfObserverLock) {

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        mContentObservable.dispatchChange(selfChange, uri);
      } else {
        mContentObservable.dispatchChange(selfChange);
      }

      if (selfChange) {
        for (Uri notifyUri : mNotifyUris) {
          mContentResolver.notifyChange(notifyUri, mSelfObserver);
        }
      }

      if (!selfChange) {
        mChangedByUris.add(uri);
      }
    }
  }

  public MultiUriCursorWrapper withNotificationUris(ContentResolver cr, Collection<Uri> uris) {
    synchronized (mSelfObserverLock) {
      mNotifyUris.addAll(uris);
      mContentResolver = cr;
      if (mSelfObserver == null) {
        mSelfObserver = new SelfContentObserver(this);
      }

      for (Uri uri : uris) {
        mContentResolver.registerContentObserver(uri, true, mSelfObserver);
      }

      mSelfObserverRegistered = true;
    }

    return this;
  }

  public MultiUriCursorWrapper withNotificationUri(ContentResolver cr, Uri uri) {
    return withNotificationUris(cr, Collections.singletonList(uri));
  }

  public Set<Uri> getNotificationUris() {
    return mNotifyUris;
  }

  @Override
  public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
    withNotificationUri(cr, notifyUri);
  }

  @Override
  public Uri getNotificationUri() {
    synchronized (mSelfObserverLock) {
      return Iterables.getFirst(mNotifyUris, null);
{'fraction_non_alphanumeric': 0.09078726968174204, 'fraction_numerical': 0.0, 'mean_word_length': 3.838465694219341, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3024168', 'n_tokens_mistral': 2634, 'n_tokens_neox': 2569, 'n_words': 524}