@Override
  public void onOperatingSystemChanged() {
    if (mSpinnerPartitionScheme == null || !mOperatingSystem.isCreationMode()) return;

    OperatingSystemEditActivity.MultibootDir location = mOperatingSystem.getLocation();
    String osType = mOperatingSystem.getOperatingSystemType();

    // check if sth. has changed
    if (mPreviousOSType != null && mPreviousLocation != null) {
      if (mPreviousOSType.equals(osType) && mPreviousLocation == location) return;
    }

    // spinner schemes
    mSpinnerSchemes.clear();
    if (location != null) {
      boolean bindSupported =
          OperatingSystem.isBindAllowed(mOperatingSystem.getLocation().mountEntry.getFsType());

      if (bindSupported) mSpinnerSchemes.add(SCHEMES.get(SCHEMEID_ANDROID_DYNSYS_BINDOTHER));
      if (bindSupported) mSpinnerSchemes.add(SCHEMES.get(SCHEMEID_ANDROID_BINDALL));
      mSpinnerSchemes.add(SCHEMES.get(SCHEMEID_ANDROID_DYNSYS_LOOPOTHER));
      mSpinnerSchemes.add(SCHEMES.get(SCHEMEID_ANDROID_LOOPALL));
    }
    mSpinnerPartitionScheme.setAdapter(
        new ArrayAdapter<>(
            getContext(), R.layout.support_simple_spinner_dropdown_item, mSpinnerSchemes));

    // update previous data
    mPreviousOSType = osType;
    mPreviousLocation = location;
  }
  @Override
  public View onCreateView(
      LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_partitionitem_list, container, false);

    //  get views
    mSpinnerPartitionScheme = (AppCompatSpinner) view.findViewById(R.id.spinner_partition_scheme);
    View schemeContainer = view.findViewById(R.id.scheme_container);

    if (mOperatingSystem.isCreationMode()) {
      // partition scheme
      mSpinnerPartitionScheme.setOnItemSelectedListener(
          new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
              PartitionScheme scheme = mSpinnerSchemes.get(position);
              scheme.mCallback.onSetDefaults();
              mOperatingSystem.notifyChange();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {}
          });
      onOperatingSystemChanged();
    } else {
      schemeContainer.setVisibility(View.GONE);
    }

    // Set the adapter
    Context context = view.getContext();
    RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.list);
    recyclerView.setLayoutManager(new LinearLayoutManager(context));
    recyclerView.setAdapter(new PartitionItemRecyclerViewAdapter(mOperatingSystem, mListener));
    return view;
  }
 @Override
 public void onDetach() {
   super.onDetach();
   mListener = null;
   mOperatingSystem.removeChangeListener(this);
   mOperatingSystem = null;
 }
  @Override
  public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OSEditFragmentInteractionListener) {
      mListener = (OSEditFragmentInteractionListener) context;
    } else {
      throw new RuntimeException(context.toString() + " must be OSEditFragmentInteractionListener");
    }

    SCHEMES.put(
        SCHEMEID_ANDROID_DYNSYS_BINDOTHER,
        new PartitionScheme(
            getContext(),
            R.string.scheme_android_dynsystem_bindother,
            new PartitionScheme.Callback() {
              @Override
              public void onSetDefaults() {
                ArrayList<OperatingSystem.Partition> list = new ArrayList<>();
                FSTab fsTab = mListener.getDeviceInfo().getFSTab();
                for (FSTabEntry entry : fsTab.getFSTabEntries()) {
                  if (!entry.isMultiboot()) continue;

                  String name = entry.getMountPoint().substring(1);
                  boolean is_bind = entry.getFsType().equals("auto");

                  int type;
                  if (name.equals("system")) type = OperatingSystem.Partition.TYPE_DYNFILEFS;
                  else if (is_bind) type = OperatingSystem.Partition.TYPE_BIND;
                  else type = OperatingSystem.Partition.TYPE_LOOP;

                  long size = -1;
                  OperatingSystemEditActivity.MultibootPartitionInfo info =
                      Util.getPartitionInfoByName(mListener.getMultibootPartitionInfo(), name);
                  if (info != null && type != OperatingSystem.Partition.TYPE_BIND) size = info.size;

                  list.add(new OperatingSystem.Partition(name, name, type, size));
                }
                mOperatingSystem.setPartitions(list);
              }
            }));

    SCHEMES.put(
        SCHEMEID_ANDROID_BINDALL,
        new PartitionScheme(
            getContext(),
            R.string.scheme_android_bindall,
            new PartitionScheme.Callback() {
              @Override
              public void onSetDefaults() {
                ArrayList<OperatingSystem.Partition> list = new ArrayList<>();
                FSTab fsTab = mListener.getDeviceInfo().getFSTab();
                for (FSTabEntry entry : fsTab.getFSTabEntries()) {
                  if (!entry.isMultiboot()) continue;

                  String name = entry.getMountPoint().substring(1);
                  boolean is_bind = entry.getFsType().equals("auto");

                  int type;
                  if (is_bind) type = OperatingSystem.Partition.TYPE_BIND;
                  else type = OperatingSystem.Partition.TYPE_LOOP;

                  long size = -1;
                  OperatingSystemEditActivity.MultibootPartitionInfo info =
                      Util.getPartitionInfoByName(mListener.getMultibootPartitionInfo(), name);
                  if (info != null && type != OperatingSystem.Partition.TYPE_BIND) size = info.size;

                  list.add(new OperatingSystem.Partition(name, name, type, size));
                }
                mOperatingSystem.setPartitions(list);
              }
            }));

    SCHEMES.put(
        SCHEMEID_ANDROID_DYNSYS_LOOPOTHER,
        new PartitionScheme(
            getContext(),
            R.string.scheme_android_dynsystem_loopother,
            new PartitionScheme.Callback() {
              @Override
              public void onSetDefaults() {
                ArrayList<OperatingSystem.Partition> list = new ArrayList<>();
                FSTab fsTab = mListener.getDeviceInfo().getFSTab();
                for (FSTabEntry entry : fsTab.getFSTabEntries()) {
                  if (!entry.isMultiboot()) continue;

                  String name = entry.getMountPoint().substring(1);
                  int type;
                  if (name.equals("system")) type = OperatingSystem.Partition.TYPE_DYNFILEFS;
                  else type = OperatingSystem.Partition.TYPE_LOOP;

                  long size = -1;
                  OperatingSystemEditActivity.MultibootPartitionInfo info =
                      Util.getPartitionInfoByName(mListener.getMultibootPartitionInfo(), name);
                  if (info != null) size = info.size;

                  list.add(new OperatingSystem.Partition(name, name, type, size));
                }
                mOperatingSystem.setPartitions(list);
              }
            }));

    SCHEMES.put(
        SCHEMEID_ANDROID_LOOPALL,
        new PartitionScheme(
            getContext(),
            R.string.scheme_android_loopall,
            new PartitionScheme.Callback() {
              @Override
              public void onSetDefaults() {
                ArrayList<OperatingSystem.Partition> list = new ArrayList<>();
                FSTab fsTab = mListener.getDeviceInfo().getFSTab();
                for (FSTabEntry entry : fsTab.getFSTabEntries()) {
                  if (!entry.isMultiboot()) continue;

                  String name = entry.getMountPoint().substring(1);

                  long size = -1;
                  OperatingSystemEditActivity.MultibootPartitionInfo info =
                      Util.getPartitionInfoByName(mListener.getMultibootPartitionInfo(), name);
                  if (info != null) size = info.size;

                  list.add(
                      new OperatingSystem.Partition(
                          name, name, OperatingSystem.Partition.TYPE_LOOP, size));
                }
                mOperatingSystem.setPartitions(list);
              }
            }));

    mOperatingSystem = mListener.getOperatingSystem();
    mOperatingSystem.addChangeListener(this);
  }